Chuyển đổi CSV sang Bảng


15

Các thách thức

Đưa ra một đầu vào CSV, xuất ra một bảng unicode thích hợp bằng cách sử dụng các ký tự hộp.

Định dạng

Bảng sẽ được định dạng bằng các quy tắc sau:

  • Chiều rộng cột sẽ bằng giá trị dài nhất của cột đó
  • Tất cả dữ liệu bảng sẽ được để lại hợp lý
  • Mỗi bảng sẽ giả sử hàng csv đầu tiên là tiêu đề
  • Bảng sẽ sử dụng các ký tự sau cho đường viền của nó:

┌ ┬ ┐ ├ ┼ ┤ └ ┴ ┘ ─ │

Thí dụ

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  │
└──────┴───┴──────┘

Quy tắc

  • Áp dụng sơ hở tiêu chuẩn
  • Bạn có thể gửi một chương trình đầy đủ, một chức năng hoặc lambda
  • Đầu vào có thể từ một tệp, một đối số chương trình hoặc bất kỳ thay thế chấp nhận được
  • Đầu ra có thể là một tập tin, trả lại hoặc bất kỳ thay thế chấp nhận được
  • Đầu vào CSV phải có cùng định dạng như được sử dụng trong ví dụ của tôi.
  • Câu trả lời ngắn nhất trong byte thắng.

Đầu vào CSV phải có dạng sau:

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

2
Tôi nghĩ về cơ bản có hai cách bạn có thể đi với định nghĩa CSV. Nếu phần thú vị của vấn đề là đầu ra, bạn có thể làm cho nó đơn giản như "phân chia dấu phẩy" và không phải lo lắng về cách trích dẫn dấu phẩy và cách trích dẫn ký tự trích dẫn. Mặt khác, bạn có thể nêu một phương pháp phân tích CSV cụ thể ("trích dẫn kép chuyển đổi chế độ trong đó dấu phẩy bị bỏ qua, hai dấu ngoặc kép liên tiếp tạo ra một trích dẫn kép theo nghĩa đen" là một cách khá phổ biến, nhưng không có nghĩa là duy nhất trong sự tồn tại).

4
Err, vấn đề nghiêm trọng: bạn chưa chỉ định điều kiện chiến thắng. Các chương trình có nghĩa là tối ưu hóa là gì? Chiều dài ( mã-golf )?

1
Ít nhất ba liên kết đầu tiên có tất cả định nghĩa CSV khác nhau (và ít nhất hai liên kết nói rằng có rất nhiều cách khác nhau để làm điều đó). Vì vậy, tôi cho rằng "CSV" cần được xác định đầy đủ hơn để sử dụng trong một câu hỏi (và các giải pháp sẽ cố gắng thoát khỏi việc phân tách trên dấu phẩy và không xử lý thoát vì nó cho phép chúng ngắn hơn).

2
Được rồi, tôi đã chỉnh sửa câu hỏi để bao gồm các chi tiết cụ thể về định dạng CSV mà tôi muốn mọi người sử dụng.
Shaun Wild

1
CRLF? Nghiêm túc? Điều đó sẽ đưa ra một hình phạt khá lớn đối với Unix, trong đó CR có nghĩa là một cái gì đó khác trong các tệp văn bản. Bạn có thể muốn thay thế nó bằng "dòng mới", cho phép dòng mới dành riêng cho hệ điều hành được sử dụng.

Câu trả lời:


10

Hãy thử (Dyalog) APL , 38 43 byte

Dòng đầu vào cuối cùng phải có một dòng mới.

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

Hãy thử trực tuyến! Trong phiên bản ngoại tuyến của Dyalog APL, thực thi ]boxing ON -style=mincho cùng hiệu ứng.

Giải trình

{... }một hàm ẩn danh đại diện cho đối số:

¯1 ⌽ ⍵ xoay dòng mới ở phía trước

(s ←... )xác định hàm s như sau và áp dụng nó

  1 ↓¨ thả ký tự đầu tiên của mỗi

  ⊢ ⊂⍨ dòng, chia ở đâu

  ⊃ = ⊢ ký tự đầu tiên bằng các ký tự trong chuỗi

',' ,¨ sau đó thêm dấu phẩy cho mỗi dòng

áp dụng hàm s cho mỗi dòng

{... }bây giờ áp dụng chức năng ẩn danh sau:

  1 ↓ ⍵ thả phần tử đầu tiên (các tiêu đề hàng)

  ↓ ⍉ ↑ chuyển danh sách các hàng thành danh sách các cột

  ↑¨ làm cho mỗi phần tử (một danh sách các mục) thành một ma trận của các mục được đệm

  ⍉ ⍪ tạo thành ma trận một cột, sau đó chuyển thành ma trận một hàng

  (⊃⍵) ⍪ đặt phần tử đầu tiên của đối số (danh sách các tiêu đề) lên trên cùng`

Lưu ý: Mặc dù các ký tự vẽ đường thẳng không được sử dụng rõ ràng trong giải pháp của tôi, chúng là một phần của bộ ký tự APL và cũng sẽ được tính là một byte đơn.


Xem ý kiến ​​trênIs input using list or array of strings (and no newlines) valid? Nope.
edc65

@ edc65 Đã sửa. Cảm ơn.
Adám

Hah, đó hiển thị đóng hộp chắc chắn đi kèm trong :) tiện dụng
Ven

2

PowerShell 3+, 365 byte

$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'┴')┘"

Tôi cảm thấy như điều này có thể được cải thiện rất nhiều nhưng tôi đã hết thời gian. Tất cả các kết thúc dòng là \nkhông \r, mã hóa là UTF8 không có BOM.


1

Vợt 578 byte

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

Ung dung:

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

Kiểm tra:

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

Đầu ra:

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

1

JavaScript (ES6 | FireFox), 286 byte

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

Sử dụng padEnd, đó là cụ thể FireFox.


1
Đây có phải là 288 byte không?
Adám

1
@ Adám ... có ...
Đã sửa

Bạn sử dụng rất nhiều, không g('└┴┘')tương đương với g└┴┘(với backticks sau gvà ở cuối)?
NoOneIsHere

1
padEndlà không chuẩn. Bạn nên chỉ định môi trường thực thi cần thiết.
Neil

1
Ngoài ra, có một vài nơi bạn viết `foo`+bar+`baz`- bạn có thể lưu một byte bằng cách sử dụng một mẫu `foo${bar}baz`.
Neil

1

JavaScript (ES6), 281 byte

Lưu ý: nhập dưới dạng một chuỗi với dòng mới - theo yêu cầu của OP. Các câu trả lời khác sử dụng danh sách chuỗi - sử dụng mảng chuỗi trong đầu vào Tôi có thể tránh được phân tách đầu tiên và cắt 9 byte.

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

Ít chơi gôn

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

Kiểm tra

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 byte

-3 byte để sử dụng %định dạng và -1 để viết tắtstr.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)]))

Yêu cầu đầu vào kèm theo trong dấu ngoặc kép.


1
Trông giống như 318 byte đối với tôi.
Adám

1
@ Adám Bạn nói đúng, tôi nhìn vào những ký tự.
Karl Napf

Không hoạt động, vì input()chỉ mất một dòng trên mỗi cuộc gọi. Bạn sẽ cần gọi input()cho đến khi không còn dòng nào, hoặc đọc trực tiếp từ đó stdin.
Movatica

Bên cạnh đó: 292 byte
Movatica

0

C #, 696 byte

Chơi gôn

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 (và đẹp hơn, bởi vì ^ điều đó không có tác dụng với bất cứ ai):

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

Kiểm tra:

┌──────┬───┬──────┐         ┌──────────┬───────────────────────────┬─────┐
|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  |         └──────────┴───────────────────────────┴─────┘
└──────┴───┴──────┘

Bằng cách nào đó, tôi tiếp tục nhận được 697 byte khi đếm số này.
Adám

@ Adám Chỉ cần kiểm tra lại, chuỗi Golfed dài 666 cột trong Visual Studio. Nhưng dù sao 666 hay 697 cũng không phải là điểm số cạnh tranh chính xác :)
Pete Arden

Bạn có một dòng mới, nhưng ngay cả khi loại bỏ nó, nó vẫn là 696 byte .
Adám

@ Adám Ah ... Tôi đã chờ đợi sự khác biệt về số lượng thư / byte để tăng tốc cho tôi. Đáng lẽ phải biết với những biểu tượng ngộ nghĩnh trong cái này (""). Đã cập nhật, cảm ơn :)
Pete Arden

Xem ý kiến ​​trênIs input using list or array of strings (and no newlines) valid? Nope.
edc65

0

Perl, 273 + 9 ( -CS -nlaF,cờ) = 282 byte

$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];{

Sử dụng:

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

Hãy thử nó trên Ideone .


0

PHP, 313 byte

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

phá vỡ

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

Kiểm tra nó tại ideone


0

APL (Dyalog Extended) , 36 25 byte SBCS

Chương trình đầy đủ. Giả sử đó ABCDEFGHIJKLMNOPQRSTUVWXYZlà tệp CSV. In ra thiết bị xuất chuẩn.

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

Hãy thử trực tuyến!

⎕A các chữ hoa Một lphabet (ngắn nhất để tham khảo built-in string)
⎕CSV đọc rằng tập tin và chuyển đổi từ CSV để ma trận
m← cửa hàng như m(cho m atrix)
1↓ thả hàng đầu tiên
 transpose
 chia thành danh sách các cột
↑¨ trộn mỗi danh sách các chuỗi thành một ma trận
(... )⍪ ngăn xếp sau trên đầu trang của rằng:
1↑m lấy hàng đầu tiên của m
⌂disp ứng dụng dfns.dispđó (thu hút dòng vẽ ký tự)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.