observatoire
observatoire

Reputation: 167

use Object.assign() in each object

I don't know why in my result for some items, the value is wrong.

var myArray = [{
    item: "my apple 1",
    value: 1
}, {
    item: "my carrot",
    value: 2
}, {
    item: "my banana",
    value: 3
}, {
    item: "my potatoe",
    value: 4
}, {
    item: "my apple 2",
    value: 0
}];


var MyArrayDefinition = [{
    item: "my apple 1",
    color: "red",
    group: "fruit",
    score: 1
}, {
    item: "my carrot",
    color: "orange",
    group: "vegetable",
    score: 0
}, {
    item: "my banana",
    color: "yellow",
    group: "fruit",
    score: 1
}, {
    item: "my apple 2",
    color: "red",
    group: "fruit",
    score: 0
}, {
    item: "my potatoe",
    color: "yellow",
    group: "vegetable",
    score: 0
}, ]

this is my function but the result is strange for the item "my apple 2"

    var result = [];
    myArray.forEach((itm, i) => {
    result.push(Object.assign({}, itm, MyArrayDefinition[i]));

I'd like

[{
item: "my apple 1",
color: "red",
group: "fruit",
score: 1,
value: 1
}, {
item: "my carrot",
color: "orange",
group: "vegetable",
score: 0,
value: 2
}, {
item: "my banana",
color: "yellow",
group: "fruit",
score: 1,
value: 3
}, {
item: "my apple 2",
color: "red",
group: "fruit",
score: 0,
value: 0
}, {
item: "my potatoe",
color: "yellow",
group: "vegetable",
score: 0,
value: 4
}];

Upvotes: 1

Views: 78

Answers (3)

SOUser
SOUser

Reputation: 44

var result = [];
myArray.forEach((itm, i) => {
result.push(Object.assign({}, itm, MyArrayDefinition[i]));

In the above line , you just need to replace the itm and MyArrayDefinition[i] in the Object.assign method.

like this ,

evar result = [];
myArray.forEach((itm, i) => {
result.push(Object.assign({}, MyArrayDefinition[i],itm));

Upvotes: -1

baao
baao

Reputation: 73231

Your code only works if the both arrays have the exact same order and length. To have it flexible, use find() and match the second object by item property.

const myArray = [{item:"my apple 1", value:1},{item:"my carrot", value:2},{item:"my banana", value:3},{item:"my potatoe", value:4},{item:"my apple 2", value:0}];
const MyArrayDefinition = [{item:"my apple 1", color:"red", group:"fruit", score:1},{item:"my carrot", color:"orange", group:"vegetable", score:0},{item:"my banana", color:"yellow", group:"fruit", score:1},{item:"my apple 2", color:"red", group:"fruit", score:0},{item:"my potatoe", color:"yellow", group:"vegetable", score:0},]

const combined = myArray.map(e => Object.assign(e, MyArrayDefinition.find(x => x.item === e.item)));
console.log(combined);

If both arrays are huge, consider to index the MyArrayDefinition first:

const myArray = [{item:"my apple 1", value:1},{item:"my carrot", value:2},{item:"my banana", value:3},{item:"my potatoe", value:4},{item:"my apple 2", value:0}];
const MyArrayDefinition = [{item:"my apple 1", color:"red", group:"fruit", score:1},{item:"my carrot", color:"orange", group:"vegetable", score:0},{item:"my banana", color:"yellow", group:"fruit", score:1},{item:"my apple 2", color:"red", group:"fruit", score:0},{item:"my potatoe", color:"yellow", group:"vegetable", score:0},]


const indices = MyArrayDefinition.map((e) => e.item);
const comb = myArray.map(e => Object.assign(e, MyArrayDefinition[indices.indexOf(e.item)]));
console.log(comb);

It seems to be a bit faster even for the small arrays, so you should benefit from it for a real world scenario. Check performance here

Upvotes: 1

user3297291
user3297291

Reputation: 23372

Your merge snippet assumes arrays that have matching items. I.e.: the index of my apple 2 has to be the same in both myArray and MyArrayDefinition.

If you want to support varying sets and still correctly merge, you could create a function that works a bit like a groupBy. Two important steps in your logic are:

  1. What makes two objects suitable for merging?
    In your case: (a, b) => a.item === b.item

  2. How do we merge two objects?
    In your case: (a, b) => Object.assign({}, a, b})

Now, we can (naively) reduce the myArray without worrying about the order:

var myArray=[{item:"my apple 1",value:1},{item:"my carrot",value:2},{item:"my banana",value:3},{item:"my potatoe",value:4},{item:"my apple 2",value:0}];
var MyArrayDefinition = [{ item: "my apple 1", color: "red", group: "fruit", score: 1 }, { item: "my carrot", color: "orange", group: "vegetable", score: 0 }, { item: "my banana", color: "yellow", group: "fruit", score: 1 }, { item: "my apple 2", color: "red", group: "fruit", score: 0 }, { item: "my potatoe", color: "yellow", group: "vegetable", score: 0 } ];

var merged = myArray.map(
  (x) => {
    const pair = MyArrayDefinition.find(y => x.item === y.item);
    return (Object.assign({}, x, pair || {}));
  });
  
console.log(merged);

Note that this function is still very inefficient, because it uses find in every loop. If you need performance, you can index your items by item key first.

Upvotes: 1

Related Questions