无需事先了解属性名称即可在d3.js中转换数据类型(检测字符串是否仅包含数字)

Hac*_*k-R 5 javascript d3.js

在d3.js中。我可以在网络应用程序中读取用户上传的CSV文件,如下所示:

d3.csv("upload.csv", function(data) {
  console.log(data[0]);
});
Run Code Online (Sandbox Code Playgroud)

这导致所有内容都以字符串形式读取。但是,我需要能够将数字数据类型视为数字。

如果我提前知道属性名称,则可以执行以下操作:

d3.csv("upload.csv", function(data) {
  data.forEach(function(d) {
    d.population = +d.population;
    d["land area"] = +d["land area"];
  });
  console.log(data[0]);
});
Run Code Online (Sandbox Code Playgroud)

但是,由于这是用户提供的数据,因此无法提前知道属性名称。有没有一种方法可以检测到字段仅包含数字,然后相应地更改数据类型?也许某种带有正则表达式测试的条件语句?

这些示例改编自教程。

Ger*_*ado 5

新答案

D3 v5.8引入了非常方便的方法d3.autotype,使此任务非常容易:

var data = d3.csvParse(d3.select("#csv").text(), d3.autoType);

console.log(data);
Run Code Online (Sandbox Code Playgroud)
pre {
  display: none;
}
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v5.min.js"></script>
<pre id="csv">header1,header2,header3
foo,foo2,1212
bar,bar2,2345
baz,baz2,7623</pre>
Run Code Online (Sandbox Code Playgroud)


原始答案

评论中所述,您可以使用正则表达式检查字符串是否仅包含数字。然后,如果有,则将其强制为一个数字。

在下面的演示中,我将使用a <pre>来存储数据,因为我无法d3.csv在Stack代码段中使用实际的功能。

在模拟的CSV中,有三列。其中之一header3有数字。我们知道这一点,但是代码却没有:它只是使用正则表达式检查所有值,并将仅包含数字的字符串强制转换为数字。

var data = d3.csvParse(d3.select("#csv").text());

data.forEach(function(d) {
  for (var key in d) {
    if (/^\d+$/.test(d[key])) {
      d[key] = +d[key]
    }
  }
});

console.log(data);
Run Code Online (Sandbox Code Playgroud)
pre {
  display: none;
  }
Run Code Online (Sandbox Code Playgroud)
<script src="https://d3js.org/d3.v4.min.js"></script>
<pre id="csv">header1,header2,header3
foo,foo2,1212
bar,bar2,2345
baz,baz2,7623</pre>
Run Code Online (Sandbox Code Playgroud)

这解决了您的问题,即“检测字符串是否仅包含数字”。但是,如果要处理负数,科学计数法和浮点数,则可以删除正则表达式并使用更优雅的方法:

在JavaScript中,NaN不等于任何事物,甚至不等于自身。由于将一元运算符与非数字运算符结合使用NaN,您可以简单地执行以下操作:

if (+d[key]===+d[key]) {
  d[key] = +d[key]
}
Run Code Online (Sandbox Code Playgroud)

这是另一个带有底片,浮点数和科学计数法的演示:

if (+d[key]===+d[key]) {
  d[key] = +d[key]
}
Run Code Online (Sandbox Code Playgroud)
var data = d3.csvParse(d3.select("#csv").text());

data.forEach(function(d) {
  for (var key in d) {
    if (+d[key]===+d[key]) {
      d[key] = +d[key]
    }
  }
});

console.log(data);
Run Code Online (Sandbox Code Playgroud)
pre {
  display: none;
  }
Run Code Online (Sandbox Code Playgroud)