Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/fields/array.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,16 @@ rows = extract(data, schema=Schema(fields=[fields.ArrayField(name='name')]))
print(rows)
```

Use `format="csv"` to read comma-separated array values.

```python script tabs=Python
from frictionless import Schema, extract, fields

data = [["name"], ["value1, value2"]]
rows = extract(data, schema=Schema(fields=[fields.ArrayField(name="name", format="csv")]))
print(rows)
```

## Reference

```yaml reference
Expand Down
13 changes: 13 additions & 0 deletions frictionless/fields/__spec__/test_array.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
("default", 1, None, {}),
("default", "3.14", None, {}),
("default", "", None, {}),
("csv", "val1,val2", ["val1", "val2"], {}),
("csv", "val1, val2", ["val1", "val2"], {}),
("csv", '"val1,val2", val3', ["val1,val2", "val3"], {}),
("csv", ["val1", "val2"], ["val1", "val2"], {}),
("csv", ("val1", "val2"), ["val1", "val2"], {}),
("csv", 1, None, {}),
],
)
def test_array_read_cell(format, source, target, options):
Expand All @@ -40,6 +46,13 @@ def test_array_read_cell_array_item():
assert notes is None


def test_array_read_cell_array_item_csv():
field = fields.ArrayField(name="name", format="csv", array_item={"type": "integer"})
cell, notes = field.read_cell("1,2,3")
assert cell == [1, 2, 3]
assert notes is None


def test_array_read_cell_array_item_type_error():
field = fields.ArrayField(name="name", array_item={"type": "integer"})
cell, notes = field.read_cell('["1", "2", "bad"]')
Expand Down
12 changes: 12 additions & 0 deletions frictionless/fields/array.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from __future__ import annotations

import csv
import json
from typing import Any, Dict, Optional

Expand Down Expand Up @@ -53,6 +54,17 @@ def cell_reader(cell: Any):
cell[index] = item_cell
return cell, notes

if self.format == "csv":
def csv_cell_reader(cell: Any):
if isinstance(cell, str):
try:
cell = next(csv.reader([cell], skipinitialspace=True))
except csv.Error:
cell = None
return cell_reader(cell)

return csv_cell_reader

return cell_reader

def create_value_reader(self):
Expand Down