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"
    }]
DeeeeRoy
  • 467
  • 2
  • 5
  • 13
  • 1
    Possible duplicate of [Add property from one array into another array with the same key (javascript)](https://stackoverflow.com/questions/52668966/add-property-from-one-array-into-another-array-with-the-same-key-javascript) – slider Oct 05 '18 at 16:30

6 Answers6

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);
Roy Scheffers
  • 3,832
  • 11
  • 31
  • 36
  • when I output this to the consol.log I get an Object { } is there any way I can get an array of objects back [ ] ? – DeeeeRoy Oct 05 '18 at 16:55
  • 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"} – Arvind Mishra Oct 06 '18 at 08:59
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);
Adam H
  • 1,750
  • 1
  • 9
  • 24
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;
}, []);
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; }
Nina Scholz
  • 376,160
  • 25
  • 347
  • 392
0

Try this with Underscore.js or Lodash

var mergedList = _.map(dataset1, function(item){
  return _.extend(item, _.findWhere(dataset2, { 
    id: item.id 
  })); 
});
Michael Mior
  • 28,107
  • 9
  • 89
  • 113
Midhun G S
  • 906
  • 9
  • 22
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)
});
imana97
  • 400
  • 2
  • 10