返回介绍

d3-dsv

发布于 2020-01-03 13:07:49 字数 13518 浏览 1447 评论 0 收藏 0

这个模块提供了一个针对分隔符文件/字符串的解析和格式化工具,大多数情况下是comma- (CSV) 或 tab - 分割(TSV)。这种扁平的格式在表格类数据中很流行如 Excel, 并且比 JSON 更节省空间。这个模块的实现基于 RFC 4180

CSVTSV 的转换以及格式化是内置的,比如解析:

d3.csvParse("foo,bar\n1,2"); // [{foo: "1", bar: "2"}, columns: ["foo", "bar"]]
d3.tsvParse("foo\tbar\n1\t2"); // [{foo: "1", bar: "2"}, columns: ["foo", "bar"]]

或者格式化:

d3.csvFormat([{foo: "1", bar: "2"}]); // "foo,bar\n1,2"
d3.tsvFormat([{foo: "1", bar: "2"}]); // "foo\tbar\n1\t2"

使用不同的分隔符,比如 "|" 来作为分割字符,则使用 d3.dsvFormat:

var psv = d3.dsvFormat("|");

console.log(psv.parse("foo|bar\n1|2")); // [{foo: "1", bar: "2"}, columns: ["foo", "bar"]]

为了在浏览器中方便的加载 CSV 文件,参考 d3-requestd3.csvd3.tsv 方法。

Installing

NPM 安装: npm install d3-dsv。此外还可以下载 latest release。可以直接从 d3js.orgstandalone library 单独的标准库或者作为 D3 4.0 的一部分引入。支持 AMD, CommonJS 以及基础的标签引入形式,如果使用标签引入则会暴露 d3 全局变量:

<script src="https://d3js.org/d3-dsv.v1.min.js"></script>
<script>

var data = d3.csvParse(string);

</script>

在浏览器中测试 d3-dsv.

API Reference

d3.csvParse(string[, row]) <>

等价于 dsvFormat(",").parse.

d3.csvParseRows(string[, row]) <>

等价于 dsvFormat(",").parseRows.

d3.csvFormat(rows[, columns]) <>

等价于 dsvFormat(",").format.

d3.csvFormatRows(rows) <>

等价于 dsvFormat(",").formatRows.

d3.tsvParse(string[, row]) <>

等价于 dsvFormat("\t").parse.

d3.tsvParseRows(string[, row]) <>

等价于 dsvFormat("\t").parseRows.

d3.tsvFormat(rows[, columns]) <>

等价于 dsvFormat("\t").format.

d3.tsvFormatRows(rows) <>

等价于 dsvFormat("\t").formatRows.

d3.dsvFormat(delimiter) <>

根据指定的 delimiter 构造一个新的 DSV 解析以及格式化。delimiter 必须是一个单字符(i.e., 一个单一的 16位的代码单元); 所以 ASCII 可以作为分隔符,而 emoji 不可以。

dsv.parse(string[, row]) <>

解析指定的 string, 返回解析后的行对象数组。

dsv.parseRows 不同, 这个方法要求 DSV 内容的第一行包含一组列名,这些列名将会被作为最终返回的数组的属性名。例如解析如下的 CSV 文件:

Year,Make,Model,Length
1997,Ford,E350,2.34
2000,Mercury,Cougar,2.38

返回的 JavaScript 数组为:

[
  {"Year": "1997", "Make": "Ford", "Model": "E350", "Length": "2.34"},
  {"Year": "2000", "Make": "Mercury", "Model": "Cougar", "Length": "2.38"}
]

返回的数组会包含一个 columns 属性表示输入数据的原始列名次序(因为解析之后成为对象类型,对象类型的属性迭代次序是不可靠的)。例如:

data.columns; // ["Year", "Make", "Model", "Length"]

如果没有指定 row 转换函数,则字段值将会是字符串。为了安全起见,没有将其自动转换为数值、日期或者其他的形式。在某些场景中,JavScript 会自动强制将字符串转为数值类型(例如使用 + 操作符), 但是更好的方式是使用 row 转换函数。

如果指定了 row 转换函数则会为每一行调用指定的函数,函数的参数依次为: 每一列的数据(d, 对象形式), 当前列的索引 i 以及列名数组。如果返回值为 null 或者 undefined 则当前行会被跳过并且最终不会出现在 dsv.parse 的解析结果中,返回值会作为当前行对象。例如:

var data = d3.csvParse(string, function(d) {
  return {
    year: new Date(+d.Year, 0, 1), // lowercase and convert "Year" to Date
    make: d.Make, // lowercase
    model: d.Model, // lowercase
    length: +d.Length // lowercase and convert "Length" to number
  };
});

注意: 使用 +parseIntparseFloat 通常刚快但也更严格. 例如, "30px" 使用 + 返回 NaN, 而使用 parseIntparseFloat 返回 30.

dsv.parseRows(string[, row]) <>

解析指定的 string, 返回一个数组的数组,每行数据以数组的形式表示.

dsv.parse 不同, 这个方法将第一行识别为数据而非列名,因此 DSV 内容中不应该再在第一行给出列名. 每一行会被解析为数组而不是对象. 并且数组的长度是可变的(取决于当前行可以被拆分为多少份). 例如解析如下没有列名行的 CSV 文件:

1997,Ford,E350,2.34
2000,Mercury,Cougar,2.38

返回的 JavaScript 数组为:

[
  ["1997", "Ford", "E350", "2.34"],
  ["2000", "Mercury", "Cougar", "2.38"]
]

如果没有指定 row 转换函数,则字段值将会是字符串。为了安全起见,没有将其自动转换为数值、日期或者其他的形式。在某些场景中,JavScript 会自动强制将字符串转为数值类型(例如使用 + 操作符), 但是更好的方式是使用 row 转换函数。

如果指定了 row 转换函数则会为每一行调用指定的函数,函数的参数依次为: 每一列的数据(d, 数组形式), 当前列的索引 i 以及列名数组。如果返回值为 null 或者 undefined 则当前行会被跳过并且最终不会出现在 dsv.parseRows 的解析结果中,返回值会作为当前行对象。例如:

var data = d3.csvParseRows(string, function(d, i) {
  return {
    year: new Date(+d[0], 0, 1), // convert first colum column to Date
    make: d[1],
    model: d[2],
    length: +d[3] // convert fourth column to number
  };
});

事实上,row 类似于将 mapfilter 应用到返回的结果中.

dsv.format(rows[, columns]) <>

将指定的 rows 对象数组格式化为 DSV 字符串。这个操作是 dsv.parse 的逆操作。行与行之间使用 \n 分开并且行内列之间使用指定的分隔符分开(比如 CSV 使用 ,)。如果行内某些数值已经包含分隔符或者换行符则使用双引号 " 来表示转义.

如果 columns 没有指定,则构成头行的列名的列表是由各行中所有对象的所有属性决定的,并且列名的次序是不确定的。如果指定了 columns,则其应该是由一组表示列名的字符串数组,并且列次序也会被确定。例如:

var string = d3.csvFormat(data, ["year", "make", "model", "length"]);

每一个行对象上的所有字段都会被强制转换为字符串。为了能对格式化操作进行更多的控制比如字段如何被格式化,首先遍历行对象数组,然后使用 dsv.formatRows。

dsv.formatRows(rows) <>

将指定行数组的数组格式化为字符串。这个操作是 dsv.parseRows 的逆操作。行与行之间使用 \n 分割,行内列与列之间使用指定的分隔符分割(比如 CSV 使用 ,)。如果值中已经包含分隔符或者换行符则使用双引号表示转义。

在显式的指定列名称时可以先使用 array.map 将对象数组转为数组的数组。例如:

var string = d3.csvFormatRows(data.map(function(d, i) {
  return [
    d.year.getFullYear(), // Assuming d.year is a Date object.
    d.make,
    d.model,
    d.length
  ];
}));

如果你乐意也可以使用 array.concat 来生成一个带有列名的数组,这样最终格式化字符串的第一行会包含列名:

var string = d3.csvFormatRows([[
    "year",
    "make",
    "model",
    "length"
  ]].concat(data.map(function(d, i) {
  return [
    d.year.getFullYear(), // Assuming d.year is a Date object.
    d.make,
    d.model,
    d.length
  ];
})));

Content Security Policy

如果 content security policy 到位的话,请注意 Byte-Order Marks

DSV 文件有时候以 byte order mark (BOM) 开始;例如从 Microsoft Excel 保存的 UTF-8 编码的 CSV 包含 BOM。在 web 上通常不是问题因为 UTF-8 解码算法 会自动删除 BOM. 但是在 Nodejs 中使用 UTF-8 编码时 不会移除 BOM

如果 BOM 没有被移除则文本的第一个字符为一个零宽度的不间断空格。所以一个带有 BOMCSV 由 Command Line Reference

dsv2dsv

dsv2dsv [options…] [file]

将指定的输入 DSV file 转换为另一种不同分隔符(或不同编码)的 DSV。如果没有指定 file 则默认读取输入流。例如将 CSV 转为 TSV

csv2tsv < example.csv > example.tsv

windows-1252 编码的 CSV 转为 utf-8 编码的 CSV:

dsv2dsv --input-encoding windows-1252 < latin1.csv > utf8.csv

csv2tsv [options…] [file]

等价于 dsv2json

dsv2json [options…] [file]

将输入的 DSVfile 转为 JSON. 如果 file 没有定义则默认从输入流中读取. 例如将 CSV 转为 JSON:

csv2json < example.csv > example.json

或者将 CSV 转为换行符分割的 JSON 流:

csv2json -n < example.csv > example.ndjson

csv2json [options…] [file]

等价于 json2dsv

json2dsv [options…] [file]

将输入的 JSONfile 转为 CSV. 如果 file 没有定义则默认从输入流中读取. 例如将 JSON 转为 CSV:

json2csv < example.json > example.csv

或者将换行符分割的 JSON 转为 CSV:

json2csv -n < example.ndjson > example.csv

csv2json [options…] [file]

等价于 json2dsv.

tsv2json [options…] [file]

等价于 json2dsv, 但是 output delimiter 默认为 tab (\t).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文