0

I am trying to create a new array of objects with a nested for loop. I am calling the Object.assign method with a spread argument to create a new object, but I think the problem lies with there being the same object key for each item and I only get an output with the last item in the loop. Here is the code:

let array1 = ["first", "second", "third", "fourth"];
let array2 = [
  [1, "a", "b", "c"],
  [2, "d", "e", "f"],
  [3, "g", "h", "i"],
  [4, "j", "k", "l"],
  [5, "m", "n", "o"]
];

let matchedVals = [];
let finalVals = [];

for (let j = 0; j < array1.length; j++) {
  for (let i = 0; i < array2.length; i++) {
    matchedVals.push({ [array2[i]]: array1[j][i] })
    finalVals.push(Object.assign(...matchedVals))
  }
}


//End Result Expected
// [
//   {
//     "first": 1,
//     "second": "a",
//     "third": "b",
//     "forth": "c"
//   }, {
//     "first": 2,
//     "second": "d",
//     "third": "e",
//     "forth": "f"
//   }, {
//     "first": 3,
//     "second": "g",
//     "third": "e",
//     "forth": "h"
//   }

//   ...

// ]

I am sure there is something simple, but I am not familiar enough with Object.Assign to understand what I can do to get around this issue.

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
unseen_damage
  • 1,346
  • 1
  • 14
  • 32
  • you're running Object.assign for every iteration of i, which looks wrong - also, Object.assign expects one target and one or more sources - what is your target? – Jaromanda X Jul 14 '17 at 01:56
  • [`...` is not an operator!](https://stackoverflow.com/questions/37151966/what-is-spreadelement-in-ecmascript-documentation-is-it-the-same-as-spread-oper/37152508#37152508) – Felix Kling Jul 14 '17 at 02:00
  • I think you mixed up the two arrays – Bergi Jul 14 '17 at 02:13

2 Answers2

2

I wouldn't use Object.assign here at all. Creating objects with single properties just to merge them together seems wasteful. Why not mutate a single object (per top level array element)?

I would use Array#map and Array#reduce or a plain old loop:

let array1 = ["first", "second", "third", "fourth"];
let array2 = [
  [1, "a", "b", "c"],
  [2, "d", "e", "f"],
  [3, "g", "h", "i"],
  [4, "j", "k", "l"],
  [5, "m", "n", "o"]
];


const finalResult = array2.map(
  values => values.reduce((obj, val, i) => (obj[array1[i]] = val, obj), {})
);
console.log(finalResult);
Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
1

The main issues with your code is the order of the for loops, which array you are using which index on, and your misuse of Object.assign

compare your for loops

for (let j = 0; j < array1.length; j++) {
    for (let i = 0; i < array2.length; i++) {
        matchedVals.push({ [array2[i]]: array1[j][i] })
        finalVals.push(Object.assign(...matchedVals))
    }
}

with this

for (let i = 0; i < array2.length; i++) {
    let matchedVals = [];
    for (let j = 0; j < array1.length; j++) {
        matchedVals.push({ [array1[j]]: array2[i][j] })
    }
    finalVals.push(Object.assign({},...matchedVals))
}

However, @FelixKling's answer is better code - I just wanted you to see where your code went wrong

Jaromanda X
  • 53,868
  • 5
  • 73
  • 87