简体   繁体   中英

Convert sub-array of objects with key-value pairs into array of arrays

I am having trouble transforming some CSV data into a format that is acceptable by the NVD3 Stacked Area Chart (example data shown here: http://nvd3.org/examples/stackedAreaData.json ). I currently have an array of objects of whose values are key-value pair objects, but need to turn this into an array of objects whose values are an array of arrays.

How it looks now:

[{"key":"path1","values":[{"key":1,"value": x},{"key":2,"value": y},{"key":3,"value": z}]},{"key":"path2","values":[{"key":1,"value": a},{"key":1,"value": b},{"key":1,"value": c}]}]

How it should look:

[{"key":"path1","values":[[1,x],[2,y],[3,z]]},{"key":"path2","values":[[1,a],[2,b],[3,c]]}]

In other words, I need to change the "values" in each object corresponding to a "path" (path1, path2, etc.) from an array of objects into an array of arrays (which are just the values of the object properties "key" and "value".

My current code is shown here:

d3.csv("http://monicawojciechowski.github.io/pathtoplayoff/full_data.csv", function(d) {
  return {
    path: +d.path,
    week: +d.week,
    playoff: +d.playoff,
    tm: d.tm,
    conf: d.conf,
    div: d.div,
    conf_div: d.conf_div
  };
  },

  function(data) {
  var rawdata = data;
  console.log(rawdata);

 var databypath_rollup = d3.nest()
 .key(function(d) {return +d.path; }).sortKeys((a, b) => d3.ascending(+a, +b))
 .key(function(d) {return +d.week; }).sortKeys((a, b) => d3.ascending(+a, +b))
 .rollup(function(leaves) {return d3.sum(leaves, function(d) {return parseFloat(d.playoff);})})
 .entries(rawdata);
console.log(databypath_rollup);

When I try to change the array of objects to an array of arrays, by doing the following:

var arrayformat = databypath_rollup.map(function(obj) {
  return Object.keys(obj).sort().map(function(key) { 
    return obj[key];
  });
});
console.log(arrayformat);

I mistakenly change the outer array of objects into an array of arrays. I want to keep the higher level of key-value pairs, while changing the sub-level into [1,y] (vs. {"key":1,"value":y})

Any thoughts?

Looks like a perfect use of Array.prototype.reduce()

Looks like you're using ES5, so here's what that would look like as ES5

let res1 = items.reduce(function(acc, item){
  return acc.concat({
    "key": item.key,
    "values": item.values.map(function(value) { return [value.key, value.value] })
  })
}, []);

And here's what that would look like as ES6

let res2 = items.reduce((acc, item) => {
  return acc.concat({
    "key": item.key,
    "values": item.values.map((value) => [value.key, value.value])
  })
}, []);

Both of the above uses this array (which fixes a syntax error in your sample)...

let items = [{ "key": "path1", "values": [{ "key": 1, "value": "x" }, { "key": 2, "value": "y" }, { "key": 3, "value": "z" }] }, { "key": "path2", "values": [{ "key": 1, "value": "a" }, { "key": 1, "value": "b" }, { "key": 1, "value": "c" }] }];

I've setup a repl on repl.it here... https://repl.it/MsQu

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM