Перетворити CSV у таблицю


15

Змагання

Враховуючи вхід CSV, виведіть правильну таблицю unicode, використовуючи символи поля.

Форматування

Форматування таблиці буде застосовано за такими правилами:

  • Ширина стовпця буде дорівнює найдовшому значенню цього стовпця
  • Усі дані таблиці будуть залишені виправданими
  • Кожна таблиця буде вважати заголовок першого рядка csv
  • У таблиці використовуються такі символи для меж:

┌ ┬ ┐ ├ ┼ ┤ └ ┴ ┘ ─ │

Приклад

Input:
Name,Age,Gender
Shaun,19,Male
Debra,19,Female
Alan,26,Male
George,15,Male

Output:
┌──────┬───┬──────┐
│Name  │Age│Gender│
├──────┼───┼──────┤
│Shaun │19 │Male  │
│Debra │19 │Female│
│Alan  │26 │Male  │
│George│15 │Male  │
└──────┴───┴──────┘

Правила

  • Застосовуються стандартні лазівки
  • Ви можете подати повну програму, функцію або лямбда
  • Вхід може бути з файлу, аргументу програми або будь-якої прийнятної альтернативи
  • Вихід може бути у файлі, повертається або будь-яка прийнятна альтернатива
  • Вхід CSV повинен мати той самий формат, що і в моєму прикладі.
  • Найкоротша відповідь у байтах виграє.

Вхід CSV повинен мати таку форму:

Header1,Header2,Header3 newline
Column1,Column2,Column3 newline
Column1,Column2,Column3 optional_newline

2
Я думаю, що в основному існує два шляхи визначення визначення CSV. Якщо цікавою частиною проблеми є результат, ви можете зробити його таким же простим, як "розділити на коми", і не потрібно турбуватися про те, як цитувати коми і як цитувати символ цитати. В іншому випадку ви можете вказати конкретний метод розбору CSV ("подвійні лапки перемикають режим, в якому коми ігноруються, дві подвійні лапки підряд видає буквальну подвійну лапочку" - досить поширений, але аж ніяк не єдиний у існуванні).

4
Помилка, серйозна проблема: ви не вказали умови перемоги. Для чого потрібно оптимізувати програми? Довжина ( код-гольф )?

1
Принаймні перші три посилання там усі визначають CSV по-різному (і принаймні два кажуть, що існує маса різних способів зробити це). Тому я припускаю, що "CSV" потрібно більш повно визначити для використання у запитанні (і що рішення намагатимуться уникнути розщеплення на коми і не обробляти втечу, оскільки це дозволяє їм бути коротшими).

2
Гаразд Я відредагував питання, щоб включити конкретні відомості про формат CSV, які я хотів би, щоб усі користувалися.
Shaun Wild

1
CRLF? Серйозно? Це дасть досить велику пеню для Unix, де CR означає щось інше в текстових файлах. Ви, мабуть, хочете просто замінити його на "новий рядок", що дозволяє використовувати специфічний для ОС новий рядок.

Відповіді:


10

Спробуйте (Dyalog) APL , 38 43 байт

Останній рядок введення повинен мати зворотний новий рядок.

{{(⊃⍵)⍪⍉⍪↑¨↓⍉↑1↓⍵}s¨',',¨(s1↓¨⊢⊂⍨⊢=⊃)¯1⌽⍵}

Спробуйте в Інтернеті!У офлайн-версії Dyalog APL виконуйте ]boxing ON -style=minдля того ж ефекту.

Пояснення

{... }анонімна функція де представлений аргумент:

¯1 ⌽ ⍵ обертайте нижню лінію вперед

(s ←... )визначте функцію s наступним чином і застосуйте її

  1 ↓¨ скиньте перший символ кожного

  ⊢ ⊂⍨ лінія, розділити куди

  ⊃ = ⊢ перший символ дорівнює символам у рядку

',' ,¨ потім додайте кому до кожного рядка

застосувати функцію s до кожного рядка

{ ... } тепер застосуйте таку анонімну функцію:

  1 ↓ ⍵ випустити перший елемент (заголовки рядків)

  ↓ ⍉ ↑ перенести список рядків у список стовпців

  ↑¨ внести кожен елемент (список записів) у матрицю вкладених записів

  ⍉ ⍪ зробити в матрицю з одним стовпцем, а потім перенести в однорядну матрицю

  (⊃⍵) ⍪ покласти перший елемент аргументу (список заголовків) на початок "

Примітка. Хоча символи малювання рядків явно не використовуються в моєму рішенні, вони є частиною набору символів APL, а також вважатимуться як одиничні байти.


Дивіться коментарі вищеIs input using list or array of strings (and no newlines) valid? Nope.
edc65

@ edc65 Виправлено. Спасибі.
Adám

Так, цей коробковий дисплей, безумовно, стане в нагоді :)
Вересень

2

PowerShell 3+, 365 байт

$d=$input|ipcsv
$h=$d[0].PSObject.Properties.Name|%{$_|Add-Member -type NoteProperty -na c -v(($d.$_+$_|measure Length -ma).Maximum)-pa}
"┌$(($h|%{'─'*$_.c})-join'┬')┐"
"│$(($h|%{$_.PadRight($_.c)})-join'│')│"
"├$(($h|%{'─'*$_.c})-join'┼')┤"
$d|%{$i=$_;"│$(($h|%{$i.$_.PadRight($_.c)})-join'│')│"}
"└$(($h|%{'─'*$_.c})-join'┴')┘"

Я відчуваю, що це можна було б значно покращити, але мені не вистачало часу. Усі закінчення рядків \nне \r, кодування - UTF8 без BOM.


1

Ракетка 578 байт

(let*((ll(map(λ(x)(string-split x","))ll))(lr list-ref)(sl string-length)(d display)(dl displayln)(nc(length(lr ll 0)))
(nl(for/list((i nc))(apply max(for/list((j ll))(sl(lr j i))))))(pl(λ(sy)(d(lr sy 0))(for((n nc))(for((m(lr nl n)))(d(lr sy 1)))
(if(< n(sub1 nc))(d(lr sy 2))(dl(lr sy 3))))))(g(λ(i n)(for((m(-(lr nl n)(sl i))))(d" ")))))(pl'("┌""─""┬""┐"))
(for((i(lr ll 0))(n(in-naturals)))(d"│")(d i)(g i n))(dl"│")(pl'("├""─""┼""┤"))(for((j(range 1(length ll))))
(for((i(lr ll j))(n nc))(d"│")(d i)(g i n))(dl"│"))(pl'("└" "─" "┴" "┘")))

Безголівки:

(define(f1 ll)
 (let* ((ll (map (λ (x)(string-split x ",")) ll))  ; use this to convert csv format to list of lists; 
         (lr list-ref)                    ; make short names of standard fns
         (sl string-length)
         (d display)
         (dl displayln)
         (nc (length (lr ll 0)))          ; number of cols; 
         (nl(for/list ((i nc))            ; get list of max string-length for each column
              (apply max
                     (for/list ((j ll))
                       (sl (lr j i))
                       ))))
         (pl (λ (sy)                      ; put lines using sent symbol list
               (d (lr sy 0)) 
               (for ((n nc))
                 (for ((m (lr nl n))) (d (lr sy 1)))
                 (if (< n (sub1 nc))
                     (d (lr sy 2))
                     (dl (lr sy 3))
                     ))))
         (g (λ (i n)                     ; pad with spaces if needed
              (for ((m (- (lr nl n) (sl i)))) (d " ")) ))) 
    ; put line above header: 
    (pl '("┌" "─" "┬" "┐"))

    ; put header: 
    (for ((i (lr ll 0)) (n (in-naturals)))
      (d "│")
      (d i)
      (g i n)
      )
    (dl "│")

    ; put line below header;
    (pl '("├" "─" "┼" "┤"))

    ; put rows: 
    (for ((j (range 1 (length ll))))
      (for ((i (lr ll j))
            (n nc))
        (d "│")
        (d i)
        (g i n)
        )
      (dl "│")
      )

    ; put bottom line: 
    (pl '("└" "─" "┴" "┘"))
    ))

Тестування:

(f (list  "Name,Age,Gender"
          "Shaun,19,Male"
          "Debra,19,Female"
          "Alan,26,Male"
          "George,15,Male"))

Вихід:

┌──────┬───┬──────┐
│Name  │Age│Gender│
├──────┼───┼──────┤
│Shaun │19 │Male  │
│Debra │19 │Female│
│Alan  │26 │Male  │
│George│15 │Male  │
└──────┴───┴──────┘

1

JavaScript (ES6 | FireFox), 286 байт

f=>(d=f.split`
`.map(a=>a.split`,`),s=d[0].map((a,i)=>d.reduce((b,c)=>(n=c[i].length)>b?n:b,0)),d=d.map(a=>`│${a.map((b,i)=>b.padEnd(s[i])).join`│`}│`),d.splice(1,0,(g=h=>h[0]+s.map(a=>'─'.repeat(a)).join(h[1])+h[2])('├┼┤')),g('┌┬┐')+`
${d.join`
`}
`+g('└┴┘'))

Використання padEnd, яке відповідає FireFox.


1
Хіба це не 288 байт?
Адам

1
@ Adám ... так ... Виправлено
Mwr247

Ви використовуєте це багато, не g('└┴┘')рівнозначне g└┴┘(із зворотними посиланнями після gта в кінці)?
NoOneIsHere

1
padEndє нестандартним. Вам слід вказати необхідне середовище виконання.
Ніл

1
Також є кілька місць, де ви пишете `foo`+bar+`baz`- ви можете зберегти байт за допомогою шаблону `foo${bar}baz`.
Ніл

1

JavaScript (ES6), 281 байт

Примітка: введіть як єдиний рядок з новими рядками - на вимогу ОП. Інші відповіді використовують список рядків - використовуючи рядок рядків у введенні, я можу уникнути першого розбиття та вирізати 9 байт.

l=>(l=l.split`
`.map(r=>r.split`,`.map((w,i)=>(v=w.length)<c[i]?w:(c[i]=v,w)),c=[k=0]),l=l.map(r=>r.map((v,i)=>(v+' '.repeat(c[i]-v.length)))),[h=c.map(x=>'─'.repeat(x)),l.shift(),h,...l,h].map(a=>'│┌├└'[j=a!=h?0:++k]+a.join('│┬┼┴'[j])+'│┐┤┘'[j]).join`
`)

Менше гольфу

l=>(
  // split input in an array of string arrays
  // meanwhile find the column widths and put them in *c*
  l = l.split`\n`.map(r=>r.split`,`.map((w,i)=>(v=w.length)<c[i]?w:(c[i]=v,w)),c=[]),

  // pad each column to the max column width
  l = l.map(r=>r.map((v,i)=>(v+' '.repeat(c[i]-v.length)))),

  // put in *h* the horizontal lines for top,bottom and head separator
  h = c.map(x => '─'.repeat(x) ),

  // add the *h* line at top, bottom and after head line
  l = [h, l.shift(), h, ...l, h],

  // rebuild a string, joining columns with '|' unless the row is *h*
  // if the row is *h* use different characters to join columns
  k = 0, 
  l.map(a=> '│┌├└'[j=a!=h?0:++k] + a.join('│┬┼┴'[j]) + '│┐┤┘'[j])
  .join`\n`  
)

Тест

F=
l=>(l=l.split`
`.map(r=>r.split`,`.map((w,i)=>(v=w.length)<c[i]?w:(c[i]=v,w)),c=[k=0]),l=l.map(r=>r.map((v,i)=>(v+' '.repeat(c[i]-v.length)))),[h=c.map(x=>'─'.repeat(x)),l.shift(),h,...l,h].map(a=>'│┌├└'[j=a!=h?0:++k]+a.join('│┬┼┴'[j])+'│┐┤┘'[j]).join`
`) 
  
function update() {
  O.textContent = F(I.value)
}
update()
#I { width:60%; height: 8em} 
<textarea id=I>Name,Age,Gender
Shaun,19,Male
Debra,19,Female
Alan,26,Male
George,15,Male</textarea><br>
<button onclick='update()'>Go</button>
<pre id=O></pre>


0

Python 3, 318 байт

-3 байти для використання %форматування та -1 для скороченняstr.join

L=[c.split(',')for c in input().split('\n')]
m=[max(len(x)for x in c)for c in zip(*L)]
L=[[""]+[d.ljust(n)for d,n in zip(c,m)]+[""]for c in L]
g=["─"*i for i in m]
J=str.join
print('\n'.join(["┌%s┐"%J("┬",g),J("│",L[0]),"├%s┤"%J("┼",g)]+[J("│",L[i])for i in range(1,len(L))]+["└%s┘"%J("┴",g)]))

Потрібен ввід, укладений у лапки.


1
Схоже, мені 318 байт.
Адам

1
@ Adám Ви маєте рацію, я подивився на символи.
Карл Напф

Не працює, тому що input()займає лише один рядок на кожен дзвінок. Вам потрібно буде зателефонувати input()до тих пір, поки не буде більше рядків або прочитати безпосередньо з stdin.
movatica

Крім того: 292 байти
movatica

0

C #, 696 байт

Гольф:

string T(string[]f){int w=f.Max(r=>r.Length),a=f.Select(r=>r.Split(',')[0].Length).Max(),b=f.Select(r=>r.Split(',')[1].Length).Max(),c=f.Select(r=>r.Split(',')[2].Length).Max();string o="",n="\r\n",d="",j=string.Concat(Enumerable.Repeat("─",a)),k=string.Concat(Enumerable.Repeat("─",b)),l=string.Concat(Enumerable.Repeat("─",c));Func<string,int,string>z=(q,p)=>{return q.PadRight(p);};d="┌"+j+"┬"+k+"┬"+l+"┐";o+=d+n;var g=f.First().Split(',');o+="|"+z(g[0],a)+"|"+z(g[1],b)+"|"+z(g[2],c)+"|";d="├"+j+"┼"+k+"┼"+l+"┤";o+=n+d+n;for(int i=1;i<f.Length;i++){var h=f[i].Split(',');o+="|"+z(h[0],a)+"|"+z(h[1],b)+"|"+z(h[2],c)+"|"+n;}d="└"+j+"┴"+k+"┴"+l+"┘";o+=d;return o;}

Unolfolf (і приємніше, тому що ^ це нікому не корисно):

public string T(string[] c)
{
  int width = c.Max(r => r.Length),
    longestFirstColumn = c.Select(r => r.Split(',')[0].Length).Max(),
    longestSecondColumn = c.Select(r => r.Split(',')[1].Length).Max(),
    longestThirdColumn = c.Select(r => r.Split(',')[2].Length).Max();

  string o = "", lr = "\r\n", border = "",
    firstColumnFiller = string.Concat(Enumerable.Repeat("─", longestFirstColumn)),
    secondColumnFiller = string.Concat(Enumerable.Repeat("─", longestSecondColumn)),
    thirdColumnFiller = string.Concat(Enumerable.Repeat("─", longestThirdColumn));

  Func<string, int, string> padRight = (a, b) => { return a.PadRight(b); };

  border = "┌" + firstColumnFiller
    + "┬" +
    secondColumnFiller + "┬"
    + thirdColumnFiller
    + "┐";

  o += border + lr;

  var firstRow = c.First().Split(',');

  o += "|" + padRight(firstRow[0], longestFirstColumn) +
    "|" + padRight(firstRow[1], longestSecondColumn) +
    "|" + padRight(firstRow[2], longestThirdColumn) + "|";

  border = "├" +
    firstColumnFiller + "┼" +
    secondColumnFiller + "┼" +
    thirdColumnFiller
    + "┤";

  o += lr + border + lr;

  for (int i = 1; i < c.Length; i++)
  {
    var row = c[i].Split(',');

    o += "|" + padRight(row[0], longestFirstColumn) + "|"
    + padRight(row[1], longestSecondColumn) + "|" +
    padRight(row[2], longestThirdColumn) + "|" + lr;
  }

  border = "└" +
    firstColumnFiller + "┴" +
    secondColumnFiller + "┴" +
    thirdColumnFiller
    + "┘";

  o += border;

  return o;
}

Тестування:

┌──────┬───┬──────┐         ┌──────────┬───────────────────────────┬─────┐
|Name  |Age|Gender|         |Name      |PPCG Challenge             |Votes|
├──────┼───┼──────┤         ├──────────┼───────────────────────────┼─────┤
|Shaun |19 |Male  |         |Pete Arden| Print all integers        | 4   |
|Debra |19 |Female|         |Pete Arden| Yes of course I'm an adult| 3   |
|Alan  |26 |Male  |         |Pete Arden| 5 Favorite Letters        | 1   |
|George|15 |Male  |         └──────────┴───────────────────────────┴─────┘
└──────┴───┴──────┘

Якось я постійно підраховую 697 байт.
Adám

@ Adám Щойно перевірено ще раз, рядок Golfed - це 666 стовпців у Visual Studio. Але ні 666, ні 697 все одно не є конкурентними результатами :)
Піт Арден

У вас є останній новий рядок, але навіть при видаленні його все одно залишається 696 байт .
Адам

@ Adám Ах ... Я чекав на розбіжність підрахунку листів / кількість байтів, щоб подолати мене. Мав би знати з цими смішними символами в цьому ("┼"). Оновлено, дякую :)
Піт Арден

Дивіться коментарі вищеIs input using list or array of strings (and no newlines) valid? Nope.
edc65

0

Perl, 273 + 9 ( -CS -nlaF,прапори) = 282 байти

$v[$.-1]=[@F];map$l[$_]<($l=length$F[$_])&&($l[$_]=$l),0..$#F}sub p{printf$p,@_}sub o{p
pop,map{$\x$l[$_],$_-$#l?$_[0]:pop}0..$#l}$p=join'%s','',(map"\%-${_}s",@l),$/;($\,$c,@c)=map
chr$_*4+9472,0,.5,3..15;o@c[8,1,0];p($c,map{$_,$c}@$_),$i++||o@c[12,6,4]for@v;o@c[10,3,2];{

Використання:

cat file.csv | perl -CS -nlaF, script.pl

Спробуйте це на Ideone .


0

PHP, 313 байт

for(;$r=fgetcsv(STDIN);$a[]=$r)foreach($r as$x=>$s)$e[$x]=max($e[$x],strlen($s));$t=["┬","┌","┐"];eval($L='foreach($e as$i=>$n)echo$t[!$i],str_repeat("─",$n);echo"$t[2]\n";');foreach($a as$k=>$r){foreach($r as$i=>$s)echo"│",str_pad($s,$e[$i]);echo"│\n";$t=["┼","├","┤"];if(!$k)eval($L);}$t=["┴","└","┘"];eval($L);

зламатися

for(;$r=fgetcsv(STDIN);$a[]=$r)                         // read csv from STDIN, append to array $a
    foreach($r as$x=>$s)$e[$x]=max($e[$x],strlen($s));  // remember max length in array $e
                                                        // print top border
$t=["┬","┌","┐"];eval($L='foreach($e as$i=>$n)echo$t[!$i],str_repeat("─",$n);echo"$t[2]\n";');
foreach($a as$k=>$r)
{
    foreach($r as$i=>$s)echo"│",str_pad($s,$e[$i]);echo"│\n";   // print row
    $t=["┼","├","┤"];if(!$k)eval($L);                           // print border below header
}
$t=["┴","└","┘"];eval($L);                              // print bottom border

Перевірте це на ideone


0

APL (Dyalog Extended) , 36 25 байт SBCS

Повна програма. Припустимо, що ABCDEFGHIJKLMNOPQRSTUVWXYZце файл CSV. Друкується до stdout.

disp(1m)⍪↑¨↓⍉1m←⎕CSVA

Спробуйте в Інтернеті!

⎕A верхній регістр A lphabet (найкоротший посилання, вбудований рядок)
⎕CSV читає цей файл та перетворює з CSV в
m← сховище матриць, оскільки m(для m atrix)
1↓ випадає перший рядок
 переносить
 розбиття на список стовпців, змішуючи
↑¨ кожен список рядків у матрицю
()⍪ Укладайте наступне:
1↑m виконайте перший рядок, який m
⌂disp застосовується dfns.dispдо цього (малює символи малювання рядків)

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.