How to Concatenate Properties from Multiple JavaScript Objects

How can I merge properties of two JavaScript objects dynamically?

ECMAScript 2018 Standard Method

You would use object spread:

let merged = {...obj1, ...obj2};

merged is now the union of obj1 and obj2. Properties in obj2 will overwrite those in obj1.

/** There's no limit to the number of objects you can merge.
* Later properties overwrite earlier properties with the same name. */
const allRules = {...obj1, ...obj2, ...obj3};

Here is also the MDN documentation for this syntax. If you're using babel you'll need the babel-plugin-transform-object-rest-spread plugin for it to work.

ECMAScript 2015 (ES6) Standard Method

/* For the case in question, you would do: */
Object.assign(obj1, obj2);

/** There's no limit to the number of objects you can merge.
* All objects get merged into the first object.
* Only the object in the first argument is mutated and returned.
* Later properties overwrite earlier properties with the same name. */
const allRules = Object.assign({}, obj1, obj2, obj3, etc);

(see MDN JavaScript Reference)


Method for ES5 and Earlier

for (var attrname in obj2) { obj1[attrname] = obj2[attrname]; }

Note that this will simply add all attributes of obj2 to obj1 which might not be what you want if you still want to use the unmodified obj1.

If you're using a framework that craps all over your prototypes then you have to get fancier with checks like hasOwnProperty, but that code will work for 99% of cases.

Example function:

/**
* Overwrites obj1's values with obj2's and adds obj2's if non existent in obj1
* @param obj1
* @param obj2
* @returns obj3 a new object based on obj1 and obj2
*/
function merge_options(obj1,obj2){
var obj3 = {};
for (var attrname in obj1) { obj3[attrname] = obj1[attrname]; }
for (var attrname in obj2) { obj3[attrname] = obj2[attrname]; }
return obj3;
}

How to concatenate properties from multiple JavaScript objects

ECMAscript 6 introduced Object.assign() to achieve this natively in Javascript.

The Object.assign() method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.

MDN documentation on Object.assign()

var o1 = { a: 1 };var o2 = { b: 2 };var o3 = { c: 3 };
var obj = Object.assign({}, o1, o2, o3);console.log(obj); // { a: 1, b: 2, c: 3 }

How to concatenate multiple properties of same element from an array?

I am assuming this is javascript (based on the question's tag). In which case the code you are trying to execute seems wrong.

Solution to Question

var list = [{firstName: "James", lastName: "M.", age: 58}, {firstName: "Rachel", lastName: "W.", age: 51}];

list.forEach((entry) => {
entry.fullName = entry.firstName + " " + entry.lastName;
});

console.log(list[0].fullName);

In this solution, I am simply looping through all the elements of the array and assigning a new property "fullName" with the values of the element's own property.

There are multiple ways to do it, this is just the most simplest way to clear your understanding.

To display the individual property

console.log(list[0].firstName);

Note, the array index accessor is after the array name list and not after the attribute/property name firstName in this case.

Also in your provided code there is no attribute firstName so do have some checks in place else it will use undefined value and might throw some error depending on your development environment.

Computed Attribute (getter accessor)

You should also think about how the array data will behave if the value of the attributes/properties changes.

For example if you change the firstName attribute/property then you need to remember to update the fullName attribute/property as well, else they will be out of sync.

The more efficient way to do this task is to have the attribute/property as a computed attribute/property (think functions or more accurately getters)

Sample Code

var list = [{
firstName: "James",
lastName: "M.",
age: 58,
get fullName() {
return this.firstName + " " + this.lastName;
},
}, {
firstName: "Rachel",
lastName: "W.",
age: 51,
get fullName() {
return this.firstName + " " + this.lastName;
},
}];

console.log(list[0].fullName);

You can learn more about getters as well as setters at JavaScript Accessors (Getters and Setters)

Merging two javascript objects into one?

Here's a function that's a bit more generic. It propagates through the object and will merge into a declared variable.

const posts = {  '2018-05-11': {    posts: 2  },  '2018-05-12': {    posts: 5  }};const notes = {  '2018-05-11': {    notes: 1  },  '2018-05-12': {    notes: 3  }};
function objCombine(obj, variable) { for (let key of Object.keys(obj)) { if (!variable[key]) variable[key] = {};
for (let innerKey of Object.keys(obj[key])) variable[key][innerKey] = obj[key][innerKey]; }}
let combined = {};objCombine(posts, combined);objCombine(notes, combined);console.log(combined)

How to merge/concatenate values of same object properties in an array of objects using lodash?

Instead of _.merge, you could try using _.mergeWith that accepts a customizer function which you can use to customize the assigned values.

From the official docs:

This method is like _.merge except that it accepts customizer which is
invoked to produce the merged values of the destination and source
properties.

let fruitSamples = [  [    {'id': 1,'type': 'apples','samples': [1, 2, 3]},    {'id': 2,'type': 'bananas','samples': [1, 2, 7]},    {'id': 3,'type': 'pears','samples': [1, 2, 3]}  ],  [    {'id': 1,'type': 'apples','samples': [5, 2, 9]},    {'id': 2,'type': 'bananas','samples': [1, 7, 7]},    {'id': 3,'type': 'pears','samples': [12, 21, 32]}  ],  [    {'id': 1,'type': 'apples','samples': [11, 2, 33]},    {'id': 2,'type': 'bananas','samples': [17, 2, 67]},    {'id': 3,'type': 'pears','samples': [91, 22, 34]}  ]];
function customizer(objValue, srcValue) { if (_.isArray(objValue)) { return objValue.concat(srcValue); }}
let test = _(fruitSamples) .flatten() .groupBy('type') .map(_.spread((...values) => { return _.mergeWith(...values, customizer); })) .value(); console.log(test);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Merge 2 arrays of objects but concat arrays if properties has the same value

You are correct in that Lodash's mergeWith doesn't merge recursively. You can manage this yourself manually.

  1. First iterate the first array and generate a map object by the name property.
  2. Then iterate the second array and check if the name property
    matches, and if so, recursively call the merge function to merge
    the two nested arrays from source and target arrays, otherwise, add
    the second array's element to the object map.
  3. Finally, convert the
    map object back to an array of the merged values.

Code:

const merge = (sourceArr, targetArr) => {
// (1) generate lookup map
const objMap = sourceArr.reduce((map, curr) => {
return {
...map,
[curr.name]: curr
};
}, {});

// (2) Merge objects, recurse on items arrays
targetArr.forEach((obj) => {
if (objMap[obj.name]) {
objMap[obj.name].items = merge(objMap[obj.name].items, obj.items);
} else {
objMap[obj.name] = obj;
}
});

// (3) Return merged values array
return Object.values(objMap);
};

const sourceObj = [
{
items: [
{ items: [{ id: "0", name: "z" }], name: "m" },
{ items: [{ id: "2", name: "q" }], name: "l" }
],
name: "c"
},
{
items: [{ items: [{ id: "4", name: "-" }], name: "v" }],
name: "d"
}
];

const targetObj = [
{
items: [
{ items: [{ id: "1", name: "d" }], name: "m" },
{ items: [{ id: "3", name: "b" }], name: "j" }
],
name: "c"
}
];

const merge = (sourceArr, targetArr) => {
const objMap = sourceArr.reduce((map, curr) => {
return {
...map,
[curr.name]: curr
};
}, {});

targetArr.forEach((obj) => {
if (objMap[obj.name]) {
objMap[obj.name].items = merge(objMap[obj.name].items, obj.items);
} else {
objMap[obj.name] = obj;
}
});

return Object.values(objMap);
};

const res = merge(sourceObj, targetObj);

console.log(res);

How to combine 2 objects with same properties-Javascript

What you are describing looks more like an array than an object. But if you want an Object with numeric keys, well you can do that:

var obj1 = { id: 33, name: 'abc', date: "12/12/12", type:"11" }var obj2 = { id: 22, name: 'abc1', date: "12/1/13", type: "33" }
let arr = [obj1, obj2]
// turn array into object:let obj_all = {...arr}console.log(obj_all)

Concatenate multiple object property values into one

I don't think there's any particularly elegant way to do this.

Since your input data has a small number fixed keys there's barely any point using a loop, so this works:

function munge(o) {
return {
prop1Copy: o.property1,
propConcat: [o.property2, o.property3, o.property4, o.property5].join(', ')
}
}

Group objects by multiple properties and merge array property

This is a fairly standard group by situation. The snippet below uses reduce() to refactor your array, but you could place the logic directly in your function as it is: http://jsfiddle.net/83st9wgh/

const input = [{ "year": "2021", "cabin": "1", "months": ["1", "2"] }, { "year": "2021", "cabin": "1", "months": ["4"] }, { "year": "2021", "cabin": "2", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["1", "2"] }, { "year": "2022", "cabin": "1", "months": ["4"] }, { "year": "2022", "cabin": "2", "months": ["1", "2"] }];

const result = input.reduce((acc, { year, cabin, months }) => {
const yearArray = (acc[year] ??= []);

let cIndex = yearArray.findIndex(o => o.cabin === cabin);
if (cIndex === -1) {
cIndex = yearArray.push({ cabin, months: [] }) - 1;
}

const monthsArray = yearArray[cIndex].months;
yearArray[cIndex].months = [...new Set(monthsArray.concat(months))];

return acc;
}, {});

console.log(JSON.stringify(result, null, 2));


Related Topics



Leave a reply



Submit