Đếm số lượng trường trong mỗi bản ghi csv


12

Hãy tưởng tượng một tệp văn bản trong đó mỗi bản ghi csv có thể có số lượng trường khác nhau. Nhiệm vụ là viết mã để xuất ra có bao nhiêu trường trong mỗi bản ghi của tệp. Bạn có thể giả sử không có dòng tiêu đề trong tệp và có thể đọc từ tệp hoặc đầu vào tiêu chuẩn, khi bạn chọn.

Bạn có thể giả sử một phiên bản của rfc4180 cho các quy tắc csv mà tôi sẽ giải thích bên dưới về định nghĩa của từng dòng của tệp. Đây là phiên bản được chỉnh sửa nhẹ của phần có liên quan của thông số kỹ thuật:

Định nghĩa định dạng CSV

  1. Mỗi bản ghi được đặt trên một dòng riêng biệt, được phân tách bằng dấu ngắt dòng (CRLF). Ví dụ:

    aaa,bbb,ccc CRLF
    zzz,yyy,xxx CRLF

  2. Bản ghi cuối cùng trong tệp có thể có hoặc không có ngắt dòng kết thúc. Ví dụ:

    aaa,bbb,ccc CRLF
    zzz,yyy,xxx

(Quy tắc 3. không áp dụng trong thử thách này)

  1. Trong mỗi bản ghi, có thể có một hoặc nhiều trường, được phân tách bằng dấu phẩy. Không gian được coi là một phần của một lĩnh vực và không nên bỏ qua.

  2. Mỗi lĩnh vực có thể hoặc không thể được bao trong dấu ngoặc kép. Nếu các trường không được đính kèm với dấu ngoặc kép, thì dấu ngoặc kép có thể không xuất hiện bên trong các trường. Ví dụ:

    "aaa","bbb","ccc" CRLF
    zzz,yyy,xxx

  3. Các trường có chứa dấu ngắt dòng (CRLF), dấu ngoặc kép và dấu phẩy phải được đặt trong dấu ngoặc kép. Ví dụ:

    "aaa","b CRLF
    bb","ccc" CRLF
    zzz,yyy,xxx

  4. Nếu dấu ngoặc kép được sử dụng để bao quanh các trường, thì dấu ngoặc kép xuất hiện bên trong một trường phải được thoát bằng cách đặt trước nó bằng dấu ngoặc kép khác. Ví dụ:

    "aaa","b""bb","ccc"

Thí dụ

Đầu vào:

,"Hello, World!"
"aaa","b""bb","ccc"
zzz,yyy,
"aaa","b 
bb","ccc","fish",""

Nên cho đầu ra:

2, 3, 3, 5

Bạn có thể cung cấp các giá trị đầu ra theo bất kỳ cách nào bạn thấy thuận tiện nhất.

Thư viện

Bạn có thể sử dụng bất kỳ thư viện nào bạn thích.


Câu trả lời tuyệt vời cho đến nay nhưng chúng tôi đang thiếu một câu trả lời dòng lệnh / bash sẽ đặc biệt thú vị.

Câu trả lời:


5

Stax , 19 12 byte

èJ§3‼}vAà○L>

Chạy và gỡ lỗi nó

Giải nén, không được chỉnh sửa và nhận xét, nó trông như thế này.

_'"/    split *all* of standard input by double quote characters
2::     keep only the even numbered elements
|j      split on newlines (implicitly concatenates array of "strings")
m       for each line, execute the rest of the program and output
  ',#^  count the number of commas occurring as substrings, and increment

Chạy cái này


1
Làm thế nào nó hoạt động?
Anush

1
@Anush: Tôi đã thêm một số thông tin.
đệ quy


3

JavaScript (ES2018), 42 59 byte

s=>s.replace(/".+?"/sg).split`\n`.map(c=>c.split`,`.length)


Về mặt kỹ thuật, đây là ES2018 do scờ trên regex. Không phải là vấn đề đó nhiều ;-) Và sử dụng nó tốt, btw!
Sản xuất ETH

2
Chức năng này chỉ xuất hiện để hoạt động trên một bản ghi tại một thời điểm. Tôi nghĩ rằng mô tả vấn đề yêu cầu xử lý toàn bộ tập tin của nhiều hồ sơ.
đệ quy

@ETHproductions, điểm tốt, sẽ cập nhật.
Rick Hitchcock

@recursive, bạn nói đúng, tôi hiểu nhầm đầu vào. Bây giờ cập nhật, mất nhiều byte.
Rick Hitchcock

3

Thạch , 12 byte

ṣ”"m2FỴ=”,§‘

Một cổng của câu trả lời Stax của đệ quy - hãy cho tín dụng!

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

Làm sao?

ṣ”"m2FỴ=”,§‘ - Link: list of characters, V
 ”"          - a double quote character = '"'
ṣ            - split (V) at ('"')
   m2        - modulo slice with two (1st, 3rd, 5th, ... elements of that)
     F       - flatten list of lists to a list
      Ỵ      - split at newlines
        ”,   - comma character = ','
       =     - equal? (vectorises)
          §  - sum each
           ‘ - increment (vectorises)
             - (as a full program implicit print)

Có thể bạn thích ṣ”"m2ẎỴċ€”,‘- được thắt chặt và ċ€đếm các dấu phẩy trong mỗi dấu phẩy.


2

Python, 63 byte

import csv
def f(s):return map(len,csv.reader(s.split("\n"))

Trả về đầu ra trong một mapđối tượng lặp .


2
Sử dụng một lambdachức năng, bạn có thể giảm xuống còn 54 byte
22 giờ 38 phút

@ovs Tôi có thể không hiểu các quy tắc nhưng TIO của bạn dường như đã chuẩn bị trước đầu vào. Điều đó có thực sự hợp lệ không?
Anush

Tôi thấy lý do tại sao nó hoạt động ngay bây giờ (chỉ nhờ @ ASCII).
Anush


2

Perl 5 .10.0, 55 53 byte

$_=shift;s/"(""|[^"])*"//g;s/^.*$/1+$&=~y:,::/gem;say

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

Giải trình:

$_=shift;          # first command-line arg
s/"(""|[^"])*"//g; # remove quoted fields
s/^.*$/            # replace each line       
  1+$&=~y:,::      # by the number of commas plus 1
/gem;
say                # print

2

Java 10, 101 byte

s->{for(var p:s.replaceAll("\"[^\"]*\"","x").split("\n"))System.out.println(p.split(",",-1).length);}

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

Giải trình:

s->{                                    // Method with String parameter and no return-type
  for(var p:s.replaceAll("\"[^\"]*\"","x") 
                                        //  Replace all words within quotes with an "x"
             .split("\n"))              //  Then split by new-line and loop over them:
    System.out.println(p.split(",",-1)  //   Split the item by comma's
                        .length);}      //   And print the length of this array

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.