Keyur
Keyur

Reputation: 1111

Merge 2 arrays of objects based on different key but same value

I have referred questions listed below, but got not related answer.

  1. How can I merge properties of two JavaScript objects dynamically?
  2. merge two json object based on key value in javascript
  3. Merge two array of objects based on a key

I have 2 arrays of objects,

OBJ1 -

[
    {
        "ID": 58895,
        "step": "Outage Agreed w/ Business"
    },
    {
        "ID": 58896,
        "step": "GMLC/E911/CMAS Significant"
    }
]

OBJ2 -

[
    {
        "type": "verification_step",
        "value": "GMLC/E911/CMAS Significant"
    },
    {
        "type": "verification_step",
        "value": "Outage Agreed w/ Business"
    }
]

I want to have the output which contains the both values in the single object based on the value of the string i.e.

[
    {
        "ID": 58896,
        "type": "verification_step",
        "step": "GMLC/E911/CMAS Significant"
    },
    {
        "ID": 58895,
        "type": "verification_step",
        "step": "Outage Agreed w/ Business"
    }
]

Please suggest me the way out. (ES6 solution - much appreciated)

Edit

The 3rd reference which have assiged as duplicate is not the scenario. The key should remain "step" and the data should be merged.

Upvotes: 0

Views: 424

Answers (6)

naro
naro

Reputation: 31

You can use lodash:

const _ = require('lodash');
const arr1 = [
    {
        "ID": 58895,
        "step": "Outage Agreed w/ Business"
    },
    {
        "ID": 58896,
        "step": "GMLC/E911/CMAS Significant"
    }
]

const arr2 = [
    {
        "type": "verification_step",
        "value": "GMLC/E911/CMAS Significant"
    },
    {
        "type": "verification_step",
        "value": "Outage Agreed w/ Business"
    }
]
const res =  _(arr1)
    .keyBy('step')
    .merge((_.keyBy(arr2, 'value')))
    .values()
    .map((value) => {
      const { ID, type, step } = value
      return {
         ID, 
         type, 
         step
      }
    })
    .value()

Upvotes: 1

Nina Scholz
Nina Scholz

Reputation: 386766

You could take a Map for ID and get this value for mapping new objects.

var array1 = [{ ID: 58895, step: "Outage Agreed w/ Business" }, { ID: 58896, step: "GMLC/E911/CMAS Significant" }],
    array2 = [{ type: "verification_step", value: "GMLC/E911/CMAS Significant" }, { type: "verification_step", value: "Outage Agreed w/ Business" }],
    map = new Map(array1.map(({ ID, step }) => [step, ID])),
    result = array2.map(({ type, value: step }) => ({ ID: map.get(step), type, step }));

console.log(result);

Upvotes: 0

Martin Chuka
Martin Chuka

Reputation: 109

Since you need ES6, you can just use the map operator and concatenate the missing value to just on object. like this

let obj=[
    {
        "type": "verification_step",
        "value": "GMLC/E911/CMAS Significant"
    },
    {
        "type": "verification_step",
        "value": "Outage Agreed w/ Business"
    }
]

const obj1=[
    {
        "ID": 58895,
        "step": "Outage Agreed w/ Business"
    },
    {
        "ID": 58896,
        "step": "GMLC/E911/CMAS Significant"
    }
]


obj.map((ob)=>{
    const found=obj1.find((e)=>{
        return e.step===ob.value;
    });
    if(found){
        ob.ID=found.ID
    }
});

There might be a typo, i just typed it but you get the idea. You need to do necessary check to avoid undefined.

Upvotes: 0

Mark
Mark

Reputation: 92461

You can probably do this as a one liner, but for readability and efficiency it might be nicer to make a lookup object based on the value you want from one of the arrays and then map the other other array using the lookup to join the other value you want. Something like:

let arr1 = [{"ID": 58895,"step": "Outage Agreed w/ Business"},{"ID": 58896,"step": "GMLC/E911/CMAS Significant"}]
let arr2 = [{"type": "verification_step","value": "GMLC/E911/CMAS Significant"},{"type": "verification_step","value": "Outage Agreed w/ Business"}]

// lookup based on value
let lookup = arr2.reduce((m, {type, value}) => m.set(value, {type}), new Map)

// merge each item based on lookup
let result = arr1.map(item =>  Object.assign({}, item, lookup.get(item.step)))

console.log(result)

Upvotes: 2

Maheer Ali
Maheer Ali

Reputation: 36594

You can use reduce() after combining both the arrays.

const arr1 = [ { "ID": 58895, "step": "Outage Agreed w/ Business" }, { "ID": 58896, "step": "GMLC/E911/CMAS Significant" } ] 

const arr2 = [ { "type": "verification_step", "value": "GMLC/E911/CMAS Significant" }, { "type": "verification_step", "value": "Outage Agreed w/ Business" } ]

const res = [...arr1,...arr2.map(({value,...rest}) => ({step:value,...rest}))].reduce((ac,a) => {
  let k = a.step;
  ac[k] = {...ac[k],...a} || a;
  return ac;
},{})
console.log(Object.values(res))

Upvotes: 2

Mohammad Quanit
Mohammad Quanit

Reputation: 120

you can just write Here's the link for testing online es6 compiler

let arr = [];
 obj1.map((val, index) => {
  if(obj2[index]) {
   arr.push({ id: val.ID, type: obj2[index].type, value: obj2[index].value })
  }
});

console.log(arr);

Upvotes: 0

Related Questions