合并来自不同CSV的对象数组

时间:2019-01-09 16:15:22

标签: javascript html csv d3.js

我正在使用D3JS可视化詹金斯收集的数据。唯一的问题是我想同时可视化多行,而为这些文件创建CSV文件的Jenkins脚本正在创建多个单独的文件。例如:

文件1:

ID;ValueA;ValueB
ID01;10;10
ID02;30;40

文件2:

ID;ValueC;ValueD
ID01;20;30
ID03;50;60

这样,合并后的最终结果应该是这样的:

ID;ValueA;ValueB;ValueC;ValueD
ID01;10;10;20;30
ID02;30;40;;
ID03;;;50;60

我的问题是concat只能执行以下操作:

ID01;10;10
ID02;30;40
ID01;20;30
ID03;50;60

1 个答案:

答案 0 :(得分:3)

有几种合并对象数组的方法,它们可能会提高速度,简洁性或可读性等。

这是一种实现方法,其中几种。首先,让我们获取已解析的CSV。由于我不能在StackOverflow片段中使用真实的CSV,因此我将使用模板文字;另外,由于CSV中包含分号,因此我将使用DSV解析器:

const file1 = `ID;ValueA;ValueB
ID01;10;10
ID02;30;40`;

const file2 = `ID;ValueC;ValueD
ID01;20;30
ID03;50;60`;

const csv1 = d3.dsvFormat(";").parse(file1);
const csv2 = d3.dsvFormat(";").parse(file2);

现在,我们基于CSV获取标题:

const headers = [...new Set(csv1.columns.concat(csv2.columns))].filter(function(d) {
  return d !== "ID"
});

最后是功能:

const mergedData = [];

csv1.concat(csv2).forEach(function(row) {
  const foundObject = mergedData.find(function(d) {
    return d.ID === row.ID
  });
  if (foundObject) {
    headers.forEach(function(d) {
      if (row[d]) foundObject[d] = row[d];
    });
  } else {
    headers.forEach(function(d) {
      if (!row[d]) row[d] = "";
    });
    mergedData.push(row)
  };
});

我们首先为合并的数据创建一个空数组。然后,我们在该数组中搜索与两个CSV中的每个对象的ID相匹配的对象:如果找到,则创建额外的列;如果找不到原始行,则以""作为不存在的列的值,这就是d3.csv()所做的。

这是演示:

const file1 = `ID;ValueA;ValueB
ID01;10;10
ID02;30;40`;

const file2 = `ID;ValueC;ValueD
ID01;20;30
ID03;50;60`;

const csv1 = d3.dsvFormat(";").parse(file1);
const csv2 = d3.dsvFormat(";").parse(file2);

const headers = [...new Set(csv1.columns.concat(csv2.columns))].filter(function(d) {
  return d !== "ID"
});

const mergedData = [];

csv1.concat(csv2).forEach(function(row) {
  const foundObject = mergedData.find(function(d) {
    return d.ID === row.ID
  });
  if (foundObject) {
    headers.forEach(function(d) {
      if (row[d]) foundObject[d] = row[d];
    });
  } else {
    headers.forEach(function(d) {
      if (!row[d]) row[d] = "";
    });
    mergedData.push(row)
  };
});

console.log(mergedData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>