CSV'yi Tabloya Dönüştür


15

Meydan okuma

Bir CSV girişi verildiğinde, kutu karakterlerini kullanarak uygun bir unicode tablo çıkarın.

Biçimlendirme

Tablo aşağıdaki kurallar kullanılarak biçimlendirilecektir:

  • Sütun genişliği, bu sütunun en uzun değerine eşit olacaktır
  • Tüm tablo verileri haklı bırakılacak
  • Her tablo ilk csv satırının başlık olduğunu varsayar
  • Tablo kenarlıkları için aşağıdaki karakterleri kullanacaktır:

┌ ┬ ┐ ├ ┼ ┤ └ ┴ ┘ ─ │

Misal

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

kurallar

  • Standart boşluklar geçerlidir
  • Tam bir program, bir işlev veya bir lambda gönderebilirsiniz.
  • Girdi bir dosyadan, program bağımsız değişkeninden veya kabul edilebilir herhangi bir alternatiften olabilir
  • Çıktı bir dosyaya, iade veya kabul edilebilir herhangi bir alternatif olabilir
  • CSV girişi, örneğimde kullanılanla aynı formatta olmalıdır.
  • Bayt cinsinden en kısa cevap kazanır.

CSV girişi aşağıdaki biçimde olmalıdır:

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

2
Bence CSV tanımıyla iki şekilde gidebilirsiniz. Sorunun ilginç kısmı çıktı ise, bunu "virgüllere ayırın" kadar basit hale getirebilir ve virgüllerin nasıl alıntılanacağı ve alıntı karakterin nasıl alıntılanacağı konusunda endişelenmenize gerek yoktur. Aksi takdirde, CSV'yi ayrıştırmanın belirli bir yöntemini belirtebilirsiniz ("çift tırnaklar, virgüllerin yoksayıldığı bir modu değiştirir, arka arkaya iki çift tırnak kelimenin tam anlamıyla çift tırnak oluşturur", ancak hiçbir şekilde tek değildir varoluşta).

4
Hata, ciddi bir sorun: Bir zafer koşulu belirlemediniz. Hangi programların optimize edilmesi gerekiyor? Uzunluk ( kod-golf )?

1
En azından ilk üç bağlantı CSV'nin tamamını farklı tanımlar (ve en az iki tanesi bunu yapmanın birçok farklı yolu olduğunu söyler). Bu yüzden, "CSV" nin bir soruda kullanılmak üzere daha tam olarak tanımlanması gerektiğini varsayıyorum (ve çözümler, virgüllerde bölünmekten ve daha kısa olmalarına izin vermeden kaçmayı ele almamaktan kurtulmaya çalışacaktır).

2
Tamam, soruyu herkesin kullanmasını istediğim CSV formatıyla ilgili bilgileri içerecek şekilde düzenledim.
Shaun Wild

1
CRLF? Ciddi anlamda? Bu, CR'nin metin dosyalarında başka bir şey ifade ettiği Unix'e oldukça büyük bir ceza verecek. Muhtemelen bunu sadece "newline" ile değiştirmek ve işletim sistemine özgü newline'ın kullanılmasına izin vermek istiyorsunuz.

Yanıtlar:


10

(Dyalog) APL'yi deneyin , 38 43 bayt

Son giriş satırının sonunda bir satırsonu olmalıdır.

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

Çevrimiçi deneyin! Dyalog APL'nin çevrimdışı sürümünde ]boxing ON -style=minaynı etkiyi yürütün .

açıklama

{ ... } argümanı temsil eden anonim bir işlev :

¯1 ⌽ ⍵ sondaki yeni satırı öne döndür

(s ←... )fonksiyonu tanımla s aşağıdaki gibi ve uygulamak

  1 ↓¨ her birinin ilk karakterini bırak

  ⊢ ⊂⍨ çizgi, nerede ayrılır

  ⊃ = ⊢ ilk karakter dizgedeki karakterlere eşittir

',' ,¨ sonra her satıra virgül koyun

s işlevini uygulaher satıra

{ ... } şimdi aşağıdaki anonim işlevi uygulayın:

  1 ↓ ⍵ ilk öğeyi bırak (satır başlıkları)

  ↓ ⍉ ↑ satır listesini sütun listesine dönüştür

  ↑¨ her bir öğeyi (bir giriş listesi) dolgulu girdiler matrisine dönüştür

  ⍉ ⍪ tek sütunlu bir matrise dönüştürün, ardından tek satırlık bir matrise dönüştürün

  (⊃⍵) ⍪ argümanın ilk öğesini (başlık listesi) en üste koyun`

Not: Çizgi çizme karakterleri benim çözümümde açıkça kullanılmasa da, bunlar APL karakter kümesinin bir parçasıdır ve tek bayt olarak sayılırlar.


Yukarıdaki yorumları görünIs input using list or array of strings (and no newlines) valid? Nope.
edc65

@ edc65 Düzeltildi. Teşekkürler.
Adam

Hah, bu kutulu ekran kesinlikle kullanışlı :)
Ven

2

PowerShell 3+, 365 bayt

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

Bunun çok gelişebileceğini hissediyorum ama zamanım bitti. Tüm satır sonları \nno ile \r, kodlama BOM olmadan UTF8'dir.


1

Raket 578 bayt

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

Test yapmak:

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

Çıktı:

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

1

JavaScript (ES6 | FireFox), 286 bayt

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

Kullanımları padEndFireFox özgü olan.


1
Bu 288 bayt değil mi?
Adam

1
@ Adám ... yes ... Sabit
Mwr247

Bunu çok kullanıyorsunuz, g('└┴┘')eşdeğeri değil g└┴┘(sonradan sonra gve sonunda backticks ile )?
NoOneIsHere

1
padEndstandart değildir. Gerekli yürütme ortamını belirtmelisiniz.
Neil

1
Ayrıca, yazdığınız birkaç yer vardır `foo`+bar+`baz`- bir şablon kullanarak bir bayt kaydedebilirsiniz `foo${bar}baz`.
Neil

1

JavaScript (ES6), 281 bayt

Not: OP tarafından istendiği gibi, yeni satırlı tek bir dize olarak giriş yapın. Diğer cevaplar bir dize listesi kullanır - girişte bir dize dizisi kullanarak ilk bölünmeyi önleyebilir ve 9 bayt kesebilir.

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

Daha az golf

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

Ölçek

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 bayt

%Biçimlendirmeyi kullanmak için -3 bayt ve kısaltmak için -1 baytstr.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)]))

Tırnak içine alınmış giriş gerektirir.


1
Bana 318 bayt gibi geliyor.
Adam

1
@ Adám Haklısın, karakterlere baktım.
Karl Napf

Çalışmıyor, çünkü input()her çağrıda yalnızca bir hat alıyor. Başka input()satır kalmayıncaya kadar aramanız veya doğrudan okuyabilmeniz gerekir stdin.
movatica

Bunun yanında: 292 bayt
movatica

0

C #, 696 Bayt

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 (ve daha hoş, çünkü ^ kimseye faydası yok):

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

Test yapmak:

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

Her nasılsa, bunu sayarken 697 bayt alıyorum.
Adam

@ Adám Sadece kontrol edildi, Golfed dize Visual Studio'da 666 sütun uzunluğunda. Ama ne 666 ne de 697 yine de tam olarak rekabetçi puanlar :)
Pete Arden

Sonunda bir satırsonu var, ancak onu kaldırırken bile , hala 696 bayt .
Adam

@ Adám Ah ... Beni harekete geçirmek için bir mektup sayımı / bayt sayımı tutarsızlığı bekliyordum. Bu komik semboller ile bu bilmeli ("┼"). Güncellendi, teşekkürler :)
Pete Arden

Yukarıdaki yorumları görünIs input using list or array of strings (and no newlines) valid? Nope.
edc65

0

Perl, 273 + 9 ( -CS -nlaF,bayraklar) = 282 bayt

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

Kullanımı:

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

Ideone üzerinde deneyin .


0

PHP, 313 bayt

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

Yıkmak

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

İdeone'de test edin


0

APL (Dyalog Genişletilmiş) , 36 25 bayt SBCS

Tam program. Bunun ABCDEFGHIJKLMNOPQRSTUVWXYZCSV dosyası olduğunu varsayar . Stdout'a yazdırır.

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

Çevrimiçi deneyin!

⎕A Büyük harf A lphabet (en kısa-to-referans yerleşik dize)
⎕CSV matris CSV o dosyayı ve dönüştürmek okundu
m← olarak mağazada m(için m Atrix)
1↓ ilk satır damla
 devrik
 sütunların listesine bölünmüş
↑¨ bir matris içine dizelerin her liste mix
()⍪ Aşağıdakilerin üstüne koyun:
1↑m ilk m
⌂disp uygulama satırını alın dfns.disp(çizgi çizme karakterleri çizer)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.