将d3.csv修改为小写列名的正确方法

时间:2014-11-18 15:56:21

标签: javascript csv d3.js

拥有一个处理客户提供的csv数据文件的应用程序。 Javascript区分大小写。但是大多数统计信息包都不区分大小写,因此列名称有不同的大小写。如果他们通过SAS,SPSS或其他程序运行文件并保存为新文件,将所有内容转换为大写或小写,则大写可以更改。

所以我修改D3使它自动将列名转换为小写。这可以通过修改d3.js源代码来添加.toLocaleUpperCase()轻松完成,如下所示:

    ...
    dsv.parse = function(text, f) {
      var o;
      return dsv.parseRows(text, function(row, i) {
        if (o) return o(row, i - 1);
        var a = new Function("d", "return {" + row.map(function(name, i) {
          return JSON.stringify(name.toLocaleUpperCase()) + ": d[" + i + "]";
        }).join(",") + "}");
        o = f ? function(row, i) {
          return f(a(row), i);
        } : a;
      });
    };
    ...

唯一的小挑战是我不能在我的代码中将其添加为小猴子补丁或插件。导入d3.dsv时会调用此代码块,这取决于d3_xhr的定义,需要d3.xhr等。所以我下载整个d3.js并按上述方法对其进行修改,并保存为d3.mod.js

可以想象,当我们需要更新d3时,这会在一两年内咬我或其他开发者。什么是正确的方式来处理像这样的mod?

1 个答案:

答案 0 :(得分:2)

您可以使用d3.csv接受的accessor来指定您希望如何转换行数据。

下面的函数接受一个对象并将其所有属性转换为小写。该示例使用d3.csv.parse()而不是d3.csv(),因为此处演示更直接,但您可以使用d3.csv()执行相同的操作。

不幸的是,每次调用此函数时都会调用此函数,而不是在读取行标题时调用此函数。也许还有更好的方法......

var string = "Year,Make,Model,Length\n" +
  "1997,Ford,E350,2.34\n" +
  "2000,Mercury,Cougar,2.38\n";

function convertPropsToLowerCase(d) {
  Object.keys(d).forEach(function(origProp) {
    var lowerCaseProp = origProp.toLocaleLowerCase();
    // if the uppercase and the original property name differ
    // save the value associated with the original prop
    // into the lowercase prop and delete the original one
    if (lowerCaseProp !== origProp) {
      d[lowerCaseProp] = d[origProp];
      delete d[origProp];
    }
  });
  return d;
}

var obj = d3.csv.parse(string, convertPropsToLowerCase);

console.log(JSON.stringify(obj,null, '\t'));
/*
[
	{
		"year": "1997",
		"make": "Ford",
		"model": "E350",
		"length": "2.34"
	},
	{
		"year": "2000",
		"make": "Mercury",
		"model": "Cougar",
		"length": "2.38"
	}
] 
*/
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>