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.
- First iterate the first array and generate a map object by the
name
property. - Then iterate the second array and check if the
name
property
matches, and if so, recursively call themerge
function to merge
the two nested arrays from source and target arrays, otherwise, add
the second array's element to the object map. - 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
Why Does Settimeout() "Break" for Large Millisecond Delay Values
Closure in JavaScript - Whats Wrong
How to Solve 'Redirect Has Been Blocked by Cors Policy: No 'Access-Control-Allow-Origin' Header'
Localstorage Access from Local File
How to Stop a Requestanimationframe Recursion/Loop
How to Open New Tab in JavaScript Without Switching to the New Tab
Changing the Order of Elements
How to Set Preview of Video File, Selecting from Input Type='File'
Img-Src' Was Not Explicitly Set, So 'Default-Src' Is Used as a Fallback
What Advantages Does Using (Function(Window, Document, Undefined) { ... })(Window, Document) Confer
JavaScript Sort Function. Sort by First Then by Second
Difference Between the 'Controller', 'Link' and 'Compile' Functions When Defining a Directive
Javascript: Using a Condition in Switch Case
Reformat String Containing Date with JavaScript
React: How to Load and Render External HTML File