Skip to content

Commit

Permalink
Add dsv.formatBody. Fixes #34.
Browse files Browse the repository at this point in the history
  • Loading branch information
mbostock committed Feb 7, 2019
1 parent 218d1a1 commit bd0a42a
Show file tree
Hide file tree
Showing 6 changed files with 53 additions and 19 deletions.
38 changes: 25 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,43 +43,51 @@ var data = d3.csvParse(string);

## API Reference

<a name="csvParse" href="#csvParse">#</a> d3.<b>csvParse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js#L5 "Source")
<a name="csvParse" href="#csvParse">#</a> d3.<b>csvParse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)(",").[parse](#dsv_parse).

<a name="csvParseRows" href="#csvParseRows">#</a> d3.<b>csvParseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js#L6 "Source")
<a name="csvParseRows" href="#csvParseRows">#</a> d3.<b>csvParseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)(",").[parseRows](#dsv_parseRows).

<a name="csvFormat" href="#csvFormat">#</a> d3.<b>csvFormat</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js#L7 "Source")
<a name="csvFormat" href="#csvFormat">#</a> d3.<b>csvFormat</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)(",").[format](#dsv_format).

<a name="csvFormatRows" href="#csvFormatRows">#</a> d3.<b>csvFormatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js#L8 "Source")
<a name="csvFormatBody" href="#csvFormatBody">#</a> d3.<b>csvFormatBody</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)(",").[formatBody](#dsv_formatBody).

<a name="csvFormatRows" href="#csvFormatRows">#</a> d3.<b>csvFormatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/csv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)(",").[formatRows](#dsv_formatRows).

<a name="tsvParse" href="#tsvParse">#</a> d3.<b>tsvParse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js#L5 "Source")
<a name="tsvParse" href="#tsvParse">#</a> d3.<b>tsvParse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)("\t").[parse](#dsv_parse).

<a name="tsvParseRows" href="#tsvParseRows">#</a> d3.<b>tsvParseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js#L6 "Source")
<a name="tsvParseRows" href="#tsvParseRows">#</a> d3.<b>tsvParseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)("\t").[parseRows](#dsv_parseRows).

<a name="tsvFormat" href="#tsvFormat">#</a> d3.<b>tsvFormat</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js#L7 "Source")
<a name="tsvFormat" href="#tsvFormat">#</a> d3.<b>tsvFormat</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)("\t").[format](#dsv_format).

<a name="tsvFormatRows" href="#tsvFormatRows">#</a> d3.<b>tsvFormatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js#L8 "Source")
<a name="tsvFormatBody" href="#tsvFormatBody">#</a> d3.<b>tsvFormatBody</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)("\t").[formatBody](#dsv_formatBody).

<a name="tsvFormatRows" href="#tsvFormatRows">#</a> d3.<b>tsvFormatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/tsv.js "Source")

Equivalent to [dsvFormat](#dsvFormat)("\t").[formatRows](#dsv_formatRows).

<a name="dsvFormat" href="#dsvFormat">#</a> d3.<b>dsvFormat</b>(<i>delimiter</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js#L30)
<a name="dsvFormat" href="#dsvFormat">#</a> d3.<b>dsvFormat</b>(<i>delimiter</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js)

Constructs a new DSV parser and formatter for the specified *delimiter*. The *delimiter* must be a single character (*i.e.*, a single 16-bit code unit); so, ASCII delimiters are fine, but emoji delimiters are not.

<a name="dsv_parse" href="#dsv_parse">#</a> *dsv*.<b>parse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js#L34 "Source")
<a name="dsv_parse" href="#dsv_parse">#</a> *dsv*.<b>parse</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js "Source")

Parses the specified *string*, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of objects representing the parsed rows.

Expand Down Expand Up @@ -123,7 +131,7 @@ var data = d3.csvParse(string, function(d) {

Note: using `+` rather than [parseInt](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseInt) or [parseFloat](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/parseFloat) is typically faster, though more restrictive. For example, `"30px"` when coerced using `+` returns `NaN`, while parseInt and parseFloat return `30`.

<a name="dsv_parseRows" href="#dsv_parseRows">#</a> <i>dsv</i>.<b>parseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js#L43 "Source")
<a name="dsv_parseRows" href="#dsv_parseRows">#</a> <i>dsv</i>.<b>parseRows</b>(<i>string</i>[, <i>row</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js "Source")

Parses the specified *string*, which must be in the delimiter-separated values format with the appropriate delimiter, returning an array of arrays representing the parsed rows.

Expand Down Expand Up @@ -160,7 +168,7 @@ var data = d3.csvParseRows(string, function(d, i) {

In effect, *row* is similar to applying a [map](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/map) and [filter](https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/filter) operator to the returned rows.

<a name="dsv_format" href="#dsv_format">#</a> <i>dsv</i>.<b>format</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js#L105 "Source")
<a name="dsv_format" href="#dsv_format">#</a> <i>dsv</i>.<b>format</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js "Source")

Formats the specified array of object *rows* as delimiter-separated values, returning a string. This operation is the inverse of [*dsv*.parse](#dsv_parse). Each row will be separated by a newline (`\n`), and each column within each row will be separated by the delimiter (such as a comma, `,`). Values that contain either the delimiter, a double-quote (`"`) or a newline will be escaped using double-quotes.

Expand All @@ -172,7 +180,11 @@ var string = d3.csvFormat(data, ["year", "make", "model", "length"]);

All fields on each row object will be coerced to strings. If the field value is null or undefined, the empty string is used. If the field value is a Date, the ISO 8601 date format is used per [*date*.toISOString](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString). For more control over which and how fields are formatted, first map *rows* to an array of array of string, and then use [*dsv*.formatRows](#dsv_formatRows).

<a name="dsv_formatRows" href="#dsv_formatRows">#</a> <i>dsv</i>.<b>formatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js#L114 "Source")
<a name="dsv_formatBody" href="#dsv_formatBody">#</a> <i>dsv</i>.<b>formatBody</b>(<i>rows</i>[, <i>columns</i>]) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js "Source")

Equivalent to [*dsv*.format](#dsv_format), but omits the header row. This is useful, for example, when appending rows to an existing file.

<a name="dsv_formatRows" href="#dsv_formatRows">#</a> <i>dsv</i>.<b>formatRows</b>(<i>rows</i>) [<>](https://github.com/d3/d3-dsv/blob/master/src/dsv.js "Source")

Formats the specified array of array of string *rows* as delimiter-separated values, returning a string. This operation is the reverse of [*dsv*.parseRows](#dsv_parseRows). Each row will be separated by a newline (`\n`), and each column within each row will be separated by the delimiter (such as a comma, `,`). Values that contain either the delimiter, a double-quote (") or a newline will be escaped using double-quotes.

Expand Down
1 change: 1 addition & 0 deletions src/csv.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ var csv = dsv(",");
export var csvParse = csv.parse;
export var csvParseRows = csv.parseRows;
export var csvFormat = csv.format;
export var csvFormatBody = csv.formatBody;
export var csvFormatRows = csv.formatRows;
18 changes: 14 additions & 4 deletions src/dsv.js
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,22 @@ export default function(delimiter) {
return rows;
}

function format(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) {
function preformatBody(rows, columns) {
return rows.map(function(row) {
return columns.map(function(column) {
return formatValue(row[column]);
}).join(delimiter);
})).join("\n");
});
}

function format(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return [columns.map(formatValue).join(delimiter)].concat(preformatBody(rows, columns)).join("\n");
}

function formatBody(rows, columns) {
if (columns == null) columns = inferColumns(rows);
return preformatBody(rows, columns).join("\n");
}

function formatRows(rows) {
Expand All @@ -123,6 +132,7 @@ export default function(delimiter) {
parse: parse,
parseRows: parseRows,
format: format,
formatBody: formatBody,
formatRows: formatRows
};
}
4 changes: 2 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export {default as dsvFormat} from "./dsv";
export {csvParse, csvParseRows, csvFormat, csvFormatRows} from "./csv";
export {tsvParse, tsvParseRows, tsvFormat, tsvFormatRows} from "./tsv";
export {csvParse, csvParseRows, csvFormat, csvFormatBody, csvFormatRows} from "./csv";
export {tsvParse, tsvParseRows, tsvFormat, tsvFormatBody, tsvFormatRows} from "./tsv";
export {default as autoType} from "./autoType";
1 change: 1 addition & 0 deletions src/tsv.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ var tsv = dsv("\t");
export var tsvParse = tsv.parse;
export var tsvParseRows = tsv.parseRows;
export var tsvFormat = tsv.format;
export var tsvFormatBody = tsv.formatBody;
export var tsvFormatRows = tsv.formatRows;
10 changes: 10 additions & 0 deletions test/csv-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,16 @@ tape("csvFormat(array, columns) coerces field values to strings", function(test)
test.end();
});

tape("csvFormatBody(array) omits the header row", function(test) {
test.deepEqual(dsv.csvFormatBody([{a: 1, b: 2}, {c: 3, b: 4}, {c: 5, a: 1, b: 2}]), "1,2,\n,4,3\n1,2,5");
test.end();
});

tape("csvFormatBody(array, columns) omits the header row", function(test) {
test.deepEqual(dsv.csvFormatBody([{a: 1, b: 2}, {c: 3, b: 4}, {c: 5, a: 1, b: 2}], ["a", "b"]), "1,2\n,4\n1,2");
test.end();
});

tape("csvFormatRows(array) takes an array of array of string as input", function(test) {
test.deepEqual(dsv.csvFormatRows([["a", "b", "c"], ["1", "2", "3"]]), "a,b,c\n1,2,3");
test.end();
Expand Down

0 comments on commit bd0a42a

Please sign in to comment.