Reputation: 69
I have an array of data, with first line being a header:
[["Date", "Key1", "Key2", "Key3", "Key4"],
["2018-11-01", "254", "-", "-", "-"],
["2018-11-02", "648", "-", "-", "-"],
["2018-11-03", "270", "170", "-", "147"],
["2018-11-04", "300", "406", "136", "208"]]
The output I would like to have to be able to use it with a D3 library graph would be:
[[Date: "2018-11-01", Key1: "254", Key2: "-", Key3: "-", Key4: "-"],
[Date: "2018-11-02", Key1: "648", Key2: "-", Key3: "-", Key4: "-"],
[Date: "2018-11-03", Key1: "270", Key2: "170", Key3: "-", Key4: "147"],
[Date: "2018-11-04", Key1: "300", Key2: "406", Key3: "136", Key4: "208"]]
I tried many unsuccessful variations to do that with javascript, using map. but I can't manage to do it... Keys are dynamic so I can't use fixed keys. Can someone help me? Thank you! Manue
Upvotes: 1
Views: 69
Reputation: 191976
You can create a zipObject
method that converts to arrays to object using Array.reduce()
, and use it with Array.map()
to combine the header array, with the other arrays:
const data = [["Date", "Key1", "Key2", "Key3", "Key4"], ["2018-11-01", "254", "-", "-", "-"], ["2018-11-02", "648", "-", "-", "-"], ["2018-11-03", "270", "170", "-", "147"], ["2018-11-04", "300", "406", "136", "208"]];
// zip two arrays to an object
const zipObject = (keys) => (values) =>
keys.reduce((r, key, i) => ({ ...r, [key]: values[i] }), {});
// convert a two dimensional array to object
const arrToObj = ([keys, ...values]) => values.map(zipObject(keys));
const result = arrToObj(data);
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 0
Reputation: 48600
You need to map your inner arrays to objects. You cannot assign key-value pairs within an array construct.
var matrix = [
[ "Date", "Key1", "Key2", "Key3", "Key4" ],
[ "2018-11-01", "254", "-", "-", "-" ],
[ "2018-11-02", "648", "-", "-", "-" ],
[ "2018-11-03", "270", "170", "-", "147" ],
[ "2018-11-04", "300", "406", "136", "208" ]
];
console.log(JSON.stringify(matrixToJsonObjectArray(matrix, true), null, 2));
function matrixToJsonObjectArray(matrix, includesHeader) {
var fields = includesHeader ? matrix[0] : range(matrix[0].length);
return (includesHeader ? matrix.slice(1) : matrix).map(row => {
var obj = {};
fields.forEach((field, i) => obj[field] = row[i]);
return obj;
});
}
function range(start, end) {
var arr = [];
if (end === undefined) end = start, start = 0;
for (var i = start; i < end; i++) arr.push(i);
return arr;
}
.as-console-wrapper { top: 0; max-height: 100% !important; }
Upvotes: 0
Reputation: 386560
For an array of objects, you could map the values and take mapped objects, which are assigned to a single object.
var data = [["Date", "Key1", "Key2", "Key3", "Key4"], ["2018-11-01", "254", "-", "-", "-"], ["2018-11-02", "648", "-", "-", "-"], ["2018-11-03", "270", "170", "-", "147"], ["2018-11-04", "300", "406", "136", "208"]],
result = data.slice(1).map(a => Object.assign(...a.map((v, i) => ({ [data[0][i]]: v }))));
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }
Upvotes: 2