Tiwelle
Tiwelle

Reputation: 69

Add key to array in javascript

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

Answers (3)

Ori Drori
Ori Drori

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

Mr. Polywhirl
Mr. Polywhirl

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

Nina Scholz
Nina Scholz

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

Related Questions