Dessiner une table de sortie SQL

12

Je suis sûr que la plupart d'entre nous ont vu des résultats SQL dans un terminal, tous soigneusement formatés en lignes et en colonnes. Si ce n'est pas le cas, voici un exemple:

+----------+-----------+----------------+
| column 1 | column 2  | column 3       |
+----------+-----------+----------------+
| data     | more data | even more data |
| etc      | just goes | on and on      |
+----------+-----------+----------------+

Votre objectif pour ce défi est, compte tenu des colonnes et des données de ligne pour un tableau, dessinez le tableau dans ce style. Il doit y avoir une ligne horizontale en haut et en bas du tableau et une juste en dessous de la ligne d'en-tête. Il doit y avoir des lignes verticales entre chaque colonne et une des deux côtés de la table. Vous devez utiliser des tuyaux pour les lignes verticales, des tirets pour les lignes horizontales et des points positifs pour leur intersection.

Détails:

  • Les données peuvent être entrées via stdin, ou comme argument d'une fonction, mais elles doivent être sous une forme quelconque de chaîne
  • Les données doivent être divisées par le délimiteur de chaîne ;
  • Les données ne seront composées que de caractères ASCII, ne seront pas citées et ne contiendront pas le délimiteur.
  • La première ligne des données sera utilisée pour les en-têtes de colonne
  • Les données auront toujours le même nombre de colonnes
  • L'entrée contiendra toujours au moins deux lignes (un en-tête, une donnée). Vous n'avez pas besoin de gérer des ensembles vides.
  • Une nouvelle ligne de fin ou précédente est autorisée
  • Chaque colonne doit être aussi large que l'élément le plus large, en remplissant les éléments les plus courts à droite (bonus -5% si vous remplissez les chiffres à gauche)
  • Il doit y avoir 1 espace de remplissage avant et après les en-têtes et les données, sauf lorsque la colonne est plus large
  • Vous n'êtes pas autorisé à utiliser le mysqlprogramme réel pour générer la table
  • Des échappatoires standard s'appliquent

Exemple d'entrée:

column 1;column 2;column 3
hello;world;test
longer data;foo;bar

Production

+-------------+----------+----------+
| column 1    | column 2 | column 3 |
+-------------+----------+----------+
| hello       | world    | test     |
| longer data | foo      | bar      |
+-------------+----------+----------+

Notation:

Le plus petit nombre d'octets gagne, bien sûr. -5% de bonus pour les numéros de rembourrage à gauche (voir détails).

Glenn Smith
la source
Y a-t-il des limites de temps sur l'exécution du programme?
Downgoat
Nan; prenez aussi longtemps que vous le souhaitez, tant qu'il se termine réellement.
Glenn Smith,
1
Quelle devrait être la sortie s'il n'y a qu'une seule ligne d'entrée?
Zgarb
Vous pouvez supposer qu'il y aura toujours au moins deux lignes d'entrée. MySQL n'affiche même pas de table pour un ensemble vide; vous n'êtes pas obligé non plus.
Glenn Smith,

Réponses:

2

CJam, 67 58 octets

' qN/';f/ff+z_.{[z,):TS*'|+f.e|T'-*'++:T\(T@~T]}z{s_W=\N}/

Essayez-le en ligne dans l' interpréteur CJam .

Dennis
la source
2

JavaScript (ES6), 262 octets

f=x=>{w=[],o=z=>y(`| ${z[m]((c,i)=>(c+' '.repeat(w[i]-c.length))).join` | `} |`),(d=x.split`
`[m='map'](r=>r.split`;`))[m](r=>r[m]((c,i)=>w[i]=Math.max(c.length,w[i]||0)));(y=console.log)(s=`+${w[m](c=>'-'.repeat(c+2)).join`+`}+`);o(d.shift());y(s);d[m](o);y(s)}

Démo

Puisqu'il s'agit d'ES6, cette démo fonctionne actuellement dans Firefox et Edge. Pour une raison quelconque, cela ne fonctionne pas dans Chrome / Opera même avec les fonctionnalités expérimentales JavaScript activées.

// Snippet stuff
console.log = x => document.getElementsByTagName('output')[0].innerHTML += x + '\n';
document.getElementsByTagName('button')[0].addEventListener('click', () => {
  f(document.getElementById('I').value);
});


// Actual code
f = x => {
  w = [], o = z => y(`| ${z[m]((c,i)=>(c+' '.repeat(w[i]-c.length))).join` | `} |`), (d = x.split `
` [m = 'map'](r => r.split `;`))[m](r => r[m]((c, i) => w[i] = Math.max(c.length, w[i] || 0)));
  (y = console.log)(s = `+${w[m](c=>'-'.repeat(c+2)).join`+`}+`);
  o(d.shift());
  y(s);
  d[m](o);
  y(s)
}
<p>
  <textarea id=I cols=80 rows=15>column 1;column 2;column 3
hello;world;test
longer data;foo;bar</textarea>
</p>
<button type=button>Go</button>
<pre><output></output></pre>

rink.attendant.6
la source