1

I need create one array based on two and more another arrays with unique keys each elements in array name of keys should be incremented This data is for plotting by Recharts but code below is incorrect, i got same value for each key

you can see demo https://jsfiddle.net/shuts13/hn52vpxf/

i have array of arrays:

const setOfArrays = [
[
{
     'dateTime': 1531612800000,
     'value': 97.0,
     'rangeMin': 79.0,
     'rangeMax': 110.0
},
{
     'dateTime': 1531512800000,
     'value': 96.0,
     'rangeMin': 79.0,
     'rangeMax': 110.0
}],
[{

      'dateTime': 1544745600000,
      'value': 82.7,
      'goal': 77.0

},{

      'dateTime': 1544745600000,
      'value': 81,
      'goal': 77.0

}],
[{
     'dateTime': 1531612800000,
     'value': 66.0,
     'rangeMin': 50.0,
     'rangeMax': 80.0
},{
     'dateTime': 1531612800000,
     'value': 65.0,
     'rangeMin': 50.0,
     'rangeMax': 80.0
}]
]

what i expected get on output

[
{
     'dateTime': 1531612800000,
     'value': 97.0,
     'rangeMin': 79.0,
     'rangeMax': 110.0,

     'dateTime1': 1544745600000,
     'value1': 82.7,
     'goal1': 77.0,

     'dateTime2': 1531612800000,
     'value2': 66.0,
     'rangeMin2': 50.0,
     'rangeMax2': 80.0

},
{
     'dateTime': 1531512800000,
     'value': 96.0,
     'rangeMin': 79.0,
     'rangeMax': 110.0,

      'dateTime1': 1544745600000,
      'value1': 81,
      'goal1': 77.0,

     'dateTime2': 1531612800000,
     'value2': 65.0,
     'rangeMin2': 50.0,
     'rangeMax2': 80.0
}
]

code what i had written is incorrect , value is duplicated, i dont know what is wrong

2
  • Your code should be in your question, and should be condensed from what you have on that fiddle Commented May 17, 2019 at 17:46
  • 1
    Should the output of merging [{a: 1}, {a: 2}] be [{a: [1,2]}] instead of [{a:1, a2:2}]? That would be a lot easier to use. Commented May 17, 2019 at 17:52

2 Answers 2

3

Use Array.reduce, Array.forEach, Object.entries, Object.values & Object.assign

  • Idea is to create an object with key as nested array index and value as the object as in the resulting array. And then use Object.values to get the result array.
  • So to create object from the given array, we will use Array.reduce where for each item in array we will perform following action
  • Iterate over the item objects array and check whether there exist an object in the reduced object for given index
  • If there is no entry found, add the entry in the object with value as object {...o}
  • Else if there is entry found, then for each key, value in the item object, update the corresponding object

Note - As the resulting object should be the length of the nested array, we know that number of keys in resulting object will be same as length of either of nested array. That is why in a[i], i is the index of nested array. For the values, we know that first object in first array will come as it is and others will be suffixed with array index j. So, we have checked for the presence of object corresponding to an index in a, because for the first array objects, it will always be undefined and hence, we will be adding the key:value in resulting object. For others, we just need to loop and suffix with parent iterator j like ${k}${j}

const setOfArrays = [[{'dateTime':1531612800000,'value':97.0,'rangeMin':79.0,'rangeMax':110.0},{'dateTime':1531512800000,'value':96.0,'rangeMin':79.0,'rangeMax':110.0}],[{'dateTime':1544745600000,'value':82.7,'goal':77.0},{'dateTime':1544745600000,'value':81,'goal':77.0}],[{'dateTime':1531612800000,'value':66.0,'rangeMin':50.0,'rangeMax':80.0},{'dateTime':1531612800000,'value':65.0,'rangeMin':50.0,'rangeMax':80.0}]];

const result = Object.values(setOfArrays.reduce((a,c,j) => {
  c.forEach((o,i) => {
    if(a[i]) Object.entries(o).forEach(([k,v]) => Object.assign(a[i], {[`${k}${j}`] : v}));
    else a[i] = {...o};
  });
  return a;
}, {}));
console.log(result);

Sign up to request clarification or add additional context in comments.

16 Comments

An explanation would be nice
I'm trying to figure out when do you decide that a new object is needed. I guess I don't understand what the OP is asking, it feels like the output would be a single object with bunch of properties, I must be missing something
@JuanMendes they are trying to merge the each index from all the inner arrays to one object
@adiga But the output is two objects?
Yes. So OP has an array of 3 arrays each of length 2 and wants to convert into an array with length 2 where wants to merge object at each index of all 3 arrays into 1
|
2

From your output, you are merging the m x n matrix to an array of n items (column-wise)

So,

  • map over the one of the inner arrays.
  • Inside, map over setOfArrays
  • Get an array of entries for the current column from each row using Object.entries(). Use flatMap to flatten the arrays returned to one array.
  • Add a suffix to each key when the row number of the matrix item is non zero.
  • Create an object from the merged entries using Object.fromEntries()

const setOfArrays = [[{'dateTime':1531612800000,'value':97.0,'rangeMin':79.0,'rangeMax':110.0},{'dateTime':1531512800000,'value':96.0,'rangeMin':79.0,'rangeMax':110.0}],[{'dateTime':1544745600000,'value':82.7,'goal':77.0},{'dateTime':1544745600000,'value':81,'goal':77.0}],[{'dateTime':1531612800000,'value':66.0,'rangeMin':50.0,'rangeMax':80.0},{'dateTime':1531612800000,'value':65.0,'rangeMin':50.0,'rangeMax':80.0}]];

const output = setOfArrays[0].map((obj, i) => {
  const entries = setOfArrays.flatMap((arr, j) => {
      const suffix = j || ''; // add index suffix for nonzero j
      return Object.entries(arr[i]).map(([k, v]) => [k+suffix, v]);
  })
  return Object.fromEntries(entries)
})

console.log(output)

1 Comment

Ha... This answer makes sense, and really elegant. @shuts13 This looks like what you were looking for.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.