1

I have two arrays of objects (If I am not using proper terminology, please forgive me. I am new to JS). The arrays dataset and dataset2, have objects with a common key id. I want to merge each object to form a new array of merged objects. As shown in datasetCombined below.

dataset = [{​
    "State": "AL",
    "id": 1000,
    "name": "Alabama",​​
    "percent_educated": 24},

    {​
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",​​
    "percent_educated": 24.6},

    {​
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",​​
    "percent_educated": 29.5
    }]

dataset2 = [{​
    "id": 1000,
    "qualified_professionals": "64,767,787",​​
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380" },

    {
    "id": 1001,
    "qualified_professionals": "783,076",​​
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036" },

    {​
    "id": 1003,
    "qualified_professionals": "8,968",​​
    "high_school": "12,519",
    "middle_school_or_lower": "4,528" 
    }]

Desired Output:

datasetCombined = [{​
    "State": "AL",
    "id": 1000,
    "name": "Alabama",​​
    "percent_educated": 24,
    "qualified_professionals": "64,767,787",​​
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380"},

    {​
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",​​
    "percent_educated": 24.6,
    "qualified_professionals": "783,076",​​
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036"},

    {​
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",​​
    "percent_educated": 29.5,
    "qualified_professionals": "8,968",​​
    "high_school": "12,519",
    "middle_school_or_lower": "4,528"
    }]
1

6 Answers 6

2

After the blunder with misreading your question I spent a bit of time and built this example for you to merge the two arrays based on the Id.

let dataset = [{
    "State": "AL",
    "id": 1000,
    "name": "Alabama",
    "percent_educated": 24
  },
  {
    "State": "AL",
    "id": 1001,
    "name": "Autauga County",
    "percent_educated": 24.6
  },
  {
    "State": "AL",
    "id": 1003,
    "name": "Baldwin County",
    "percent_educated": 29.5
  }
];

let dataset2 = [{
    "id": 1000,
    "qualified_professionals": "64,767,787",
    "high_school": "58,820,411",
    "middle_school_or_lower": "27,818,380"
  },
  {
    "id": 1001,
    "qualified_professionals": "783,076",
    "high_school": "1,009,593",
    "middle_school_or_lower": "496,036"
  },
  {
    "id": 1003,
    "qualified_professionals": "8,968",
    "high_school": "12,519",
    "middle_school_or_lower": "4,528"
  }
];

// create a function to reduce your arrays
let reducer = function(accumulator, currentValue, currentIndex, array) {
   // check if the item already exists in the array
	let found = accumulator.find((item) => item.id == currentValue.id);
  
  if (found) {
    // if it exists then use assign to merge the two values
    Object.assign(found, currentValue)
  } else {
    // doesn't exist, just add it to the array
  	accumulator.push(currentValue);
  }
  
  return accumulator;
}

let datasetCombined = [];

dataset.reduce(reducer, datasetCombined);
dataset2.reduce(reducer, datasetCombined);

console.log(datasetCombined);

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

Comments

2

A possible solution to the above problem could be:

Object.assign(b, a);

This way b would have both its own properties and a‘s properties. However, we might want to avoid modifying b. In such a case, we can introduce a new, empty object and copy properties from a and b to it.

const c = Object.assign({}, a, b);

And If for some reason you cannot use ES6 language features in your application, you can resort to using the Lodash library.

const c = _.assign({}, a, b);

2 Comments

when I output this to the consol.log I get an Object { } is there any way I can get an array of objects back [ ] ?
I tried the same in chrome browser console and i got the output, please try below code snippets: const a = { name: "John", age: 23 }; const b = { job: "Analyst" }; const c = Object.assign({}, a, b); type c in console and you will get result as {name: "John", age: 23, job: "Analyst"}
1

You could use Array.prototype.reduce:

const datasetCombined = dataset1.reduce((acc, next) => {
    const combinedItem = Object.assign(
        {},
        next,
        dataset2.find(item => (item.id = next.id))
    );
    acc.push(combinedItem);
    return acc;
}, []);

Comments

1

You could look for the id and append an existing object or push a copy of the object to the result set.

This works for an arbitrary count of arrays.

var dataset = [{ State: "AL", id: 1000, name: "Alabama", percent_educated: 24 }, { State: "AL", id: 1001, name: "Autauga County", percent_educated: 24.6 }, { State: "AL", id: 1003, name: "Baldwin County", percent_educated: 29.5 }],
    dataset2 = [{ id: 1000, qualified_professionals: "64,767,787", high_school: "58,820,411", middle_school_or_lower: "27,818,380" }, { id: 1001, qualified_professionals: "783,076", high_school: "1,009,593", middle_school_or_lower: "496,036" }, { id: 1003, qualified_professionals: "8,968", high_school: "12,519", middle_school_or_lower: "4,528" }],
    result = [dataset, dataset2].reduce((r, a) => {
        a.forEach(o => {
            var temp = r.find(({ id }) => o.id === id);
            if (!temp) {
                r.push(Object.assign({}, o));
            } else {
                Object.assign(temp, o);
            }
        });
        return r;
    }, []);
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

A slightly better approach with a Map.

var dataset = [{ State: "AL", id: 1000, name: "Alabama", percent_educated: 24 }, { State: "AL", id: 1001, name: "Autauga County", percent_educated: 24.6 }, { State: "AL", id: 1003, name: "Baldwin County", percent_educated: 29.5 }],
    dataset2 = [{ id: 1000, qualified_professionals: "64,767,787", high_school: "58,820,411", middle_school_or_lower: "27,818,380" }, { id: 1001, qualified_professionals: "783,076", high_school: "1,009,593", middle_school_or_lower: "496,036" }, { id: 1003, qualified_professionals: "8,968", high_school: "12,519", middle_school_or_lower: "4,528" }],
    result = Array.from([dataset, dataset2].reduce(
        (r, a) => a.reduce((m, o) => m.set(o.id, Object.assign(m.get(o.id) || {}, o)), r),
        new Map
    ).values());
    
console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

Comments

0

Try this with Underscore.js or Lodash

var mergedList = _.map(dataset1, function(item){
  return _.extend(item, _.findWhere(dataset2, { 
    id: item.id 
  })); 
});

2 Comments

You should specify this is using a third party library and which one.
Noted. Thanks @alexander
0

If you are not using ES6 and you don't want to use any library like Lodash, and If The number of objects in both arrays are equal and they are in order by the id property (as shown in your example), then you can use the code bellow:

var datasetCombined = [];

dataset.map(function(obj,keyNo){
  for (var key in dataset2[keyNo]){
    obj[key]=dataset2[keyNo][key];
  }
  datasetCombined.push(obj)
});

Comments

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.