TehEbil
TehEbil

Reputation: 88

Optimization of double for with .map / .filter / .reduce or something

Is there a way to optimize the following with ES5 / ES6?

var obj = [];
var set;
for (var key_s in data1) {
    set = false;
    for (var key_s2 in data2) {
        if (data1[key_s].id === data2[key_s2].id) {
            obj.push({'id': data1[key_s].id,
                      'key': data1[key_s].key,
                      'value': data2[key_s2].value})
            set = true;
            break;
        }
    }
    if (!set)
        obj.push({'id': data1[key_s].id,
                  'key': data1[key_s].key,
                  'value': "EMPTY"})
}

I want to have an object which contains all keys of data1 and if a pair got the same id like the one in data2, it should take its value, otherwise it should become 'EMPTY'. Or maybe is there a way to use Object.assign with some special parameters or something?

Upvotes: 1

Views: 206

Answers (3)

castletheperson
castletheperson

Reputation: 33516

You could do it with Array#map, Array#find and Object.assign. By specifying the value in the first parameter of Object.assign, you can set a default to be overridden by the object from data2.

var obj = data1.map(obj1 => {
  const obj2 = data2.find(obj2 => obj1.id === obj2.id);
  return Object.assign({ value: 'EMPTY' }, obj1, obj2);
});

Using spread properties, that Object.assign could be changed to:

{ value: 'EMPTY', ...obj1, ...obj2 }

Upvotes: 0

Jay Hamilton
Jay Hamilton

Reputation: 114

This is pretty es6'ed. map over data1, the .find will return the matching object if one exists or else return undefined. set key_s.value to either the key_s2 value or "EMPTY" and then return the key_s object. You will end up with an array of objects. This assumes that data1 and data2 are arrays of objects, that is how your example was written so I figured it was the case.

let obj = data1.map(key_s => {
  let newValue = data2.find(key_s2 => key_s.id === key_s2.id)
  key_s.value = newValue ? newValue.value : "EMPTY"
  return key_s
 })
})

Upvotes: 0

Nina Scholz
Nina Scholz

Reputation: 386868

You could use Map for data2 and use Array#map with data1 and the possible value of data2.

var map = new Map(data2.map(o => ([o.id, o]))),
    obj = data1.map(({ id, key }) => ({ id, key, value: map.has(id)
        ? map.get(id).value
        : 'EMPTY'
    }));

Upvotes: 1

Related Questions