Narysuj tabelę wyników SQL

12

Jestem pewien, że większość z nas widziała wyniki SQL w terminalu, wszystkie starannie sformatowane w wiersze i kolumny. Jeśli nie, oto przykład:

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

Twoim celem tego wyzwania jest, biorąc pod uwagę kolumny i dane wierszy dla tabeli, narysować tabelę w tym stylu. Na górze i na dole tabeli powinna znajdować się pozioma linia oraz jedna tuż pod wierszem nagłówka. Pomiędzy każdą kolumną powinny znajdować się pionowe linie i jedna po obu stronach stołu. Należy używać rur dla linii pionowych, łączników dla linii poziomych i znaków plus dla miejsca ich przecięcia.

Specyfika:

  • Dane mogą być wprowadzane przez stdin lub jako argument funkcji, ale muszą być w postaci łańcucha
  • Dane powinny być podzielone przez ogranicznik łańcucha ;
  • Dane będą się składać tylko ze znaków ASCII, nie będą cytowane i nie będą zawierać ogranicznika.
  • Pierwszy wiersz danych zostanie wykorzystany do nagłówków kolumn
  • Dane zawsze będą miały tę samą liczbę kolumn
  • Dane wejściowe zawsze będą zawierać co najmniej dwa wiersze (jeden nagłówek, jeden dane). Nie musisz obsługiwać pustych zestawów.
  • Końcowy lub poprzedni znak nowej linii jest dozwolony
  • Każda kolumna powinna być tak szeroka jak najszerszy element, dopełniając krótsze elementy po prawej stronie (premia -5%, jeśli wprowadzisz liczby po lewej)
  • Przed i za nagłówkami i danymi powinna znajdować się 1 przestrzeń dopełnienia, z wyjątkiem sytuacji, gdy kolumna jest szersza
  • Nie wolno używać rzeczywistego mysqlprogramu do generowania tabeli
  • Obowiązują standardowe luki

Przykładowe dane wejściowe:

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

Wynik

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

Punktacja:

Oczywiście wygrywa najmniejsza liczba bajtów. -5% bonusu za numery dopełniające po lewej stronie (patrz szczegóły).

Glenn Smith
źródło
Czy są jakieś ograniczenia czasowe dla programu?
Downgoat
Nie; tak długo, jak chcesz, dopóki faktycznie się skończy.
Glenn Smith
1
Jaki powinien być wynik, jeśli istnieje tylko jeden wiersz danych wejściowych?
Zgarb
Możesz założyć, że zawsze będą co najmniej dwa wiersze danych wejściowych. MySQL nawet nie wyświetla tabeli dla pustego zestawu; ty też nie musisz.
Glenn Smith

Odpowiedzi:

2

JavaScript (ES6), 262 bajty

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)}

Próbny

Ponieważ jest to ES6, to demo działa obecnie w Firefox i Edge. Z jakiegoś powodu nie działa w przeglądarce Chrome / Opera, nawet jeśli włączono eksperymentalne funkcje JavaScript.

// 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>

lodowisko. dozorca 6
źródło