Конвертировать 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, который я хотел бы, чтобы все использовали.
Шон Уайлд,

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 Исправлено. Благодарю.
Адам

Ха, этот коробочный дисплей наверняка пригодится :)
Ven

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 без спецификации.


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'("└" "─" "┴" "┘")))

Ungolfed:

(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 байт

Примечание: вводите как одну строку с символами новой строки - по запросу OP. Другие ответы используют строковый список - используя строковый массив во входных данных, я могу избежать первого разбиения и сокращения 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.
Моватика

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

0

C #, 696 байт

Golfed:

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

Ungolfed (и приятнее, потому что ^ это никому не нужно):

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 Только что снова проверил, длина строки 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. Печать на стандартный вывод.

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

Попробуйте онлайн!

⎕A в верхнем регистре lphabet (кратчайший к ссылке встроенной в строке)  читать файл и конвертирование из CSV для матрицы  магазина как (для м Atrix)  падения первой строки  транспонирования  раскола в список столбцов  смешиваться каждый список строк в матрицу ...  сложите следующее:  возьмите первый ряд  применения к нему (рисует символы рисования линий)
⎕CSV
m←m
1↓


↑¨
()⍪
1↑mm
⌂dispdfns.disp

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.