Порахуйте кількість полів у кожному записі csv


12

Уявіть текстовий файл, де кожен запис csv може мати різну кількість полів. Завдання полягає в тому, щоб написати код, щоб вивести, скільки полів є в кожному записі файла. Ви можете припустити, що у файлі немає рядка заголовка, і ви можете читати його з файлу чи стандартного вводу, як вам захочеться.

Ви можете припустити версію rfc4180 для правил csv, яку я поясню нижче для визначення кожного рядка файлу. Ось злегка відредагована версія відповідної частини специфікації:

Визначення формату CSV

  1. Кожен запис розташований на окремому рядку, відмежованому перервою рядка (CRLF). Наприклад:

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

  2. Останній запис у файлі може мати або не мати розриву закінчення рядка. Наприклад:

    aaa,bbb,ccc CRLF
    zzz,yyy,xxx

(Правило 3. у цьому виклику не застосовується)

  1. У межах кожного запису може бути одне або кілька полів, розділених комами. Пробіли вважаються частиною поля і їх не слід ігнорувати.

  2. Кожне поле може бути або не може бути укладено у подвійні лапки. Якщо поля не укладені подвійними лапками, то подвійні лапки можуть не з’являтися всередині полів. Наприклад:

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

  3. Поля, що містять розриви рядків (CRLF), подвійні лапки та коми повинні бути укладені у подвійні лапки. Наприклад:

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

  4. Якщо для закриття полів використовуються подвійні лапки, то подвійну цитату, що з’являється всередині поля, необхідно уникнути, передуючи їй ще однією подвійною цитатою. Наприклад:

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

Приклад

Вхід:

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

Слід дати вихід:

2, 3, 3, 5

Ви можете дати вихідні значення будь-яким способом, який вам зручніше.

Бібліотеки

Ви можете використовувати будь-яку бібліотеку, яка вам подобається.


Наразі чудові відповіді, але нам не вистачає відповіді командного рядка / bash, що було б особливо класно.

Відповіді:


5

Стакс , 19 12 байт

èJ§3‼}vAà○L>

Запустіть і налагоджуйте його

Розпакований, неозорений та коментований, це виглядає приблизно так.

_'"/    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

Виконати цей


1
Як це працює?
Ануш

1
@Anush: Я додав ще трохи інформації.
рекурсивна


3

JavaScript (ES2018), 42 59 байт

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


Технічно це ES2018 через sпрапор на регулярному виразі . Не те, що так важливо ;-) І приємно користуватися ним, btw!
ETHproductions

2
Ця функція, здається, працює лише на одному записі одночасно. Я думаю, що опис проблеми вимагає обробки всього файлу з декількох записів.
рекурсивний

@ETHproductions, хороший момент, оновиться.
Рік Хічкок

@recursive, ти маєш рацію, я неправильно зрозумів матеріали. Зараз оновлено, втрачаючи багато багатьох байтів.
Рік Хічкок

3

Желе , 12 байт

ṣ”"m2FỴ=”,§‘

Порт рекурсивної відповіді Стакса - іди, дай кредит!

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

Як?

ṣ”"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)

Можливо, ви віддаєте перевагу ṣ”"m2ẎỴċ€”,‘- підтягуйте і ċ€рахує коми в кожному.


2

Пітон, 63 байти

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

Повертає результат в ітерабельному mapоб'єкті.


2
Використовуючи lambdaфункцію, ви можете
звести

@ovs Я, можливо, не розумію правил, але TIO, схоже, попередньо ввів введення. Це дійсно дійсно?
Ануш

Я бачу, чому це працює зараз (завдяки @ ASCII).
Ануш


2

Perl 5 .10.0, 55 53 байт

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

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

Пояснення:

$_=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 байт

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

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

Пояснення:

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

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