I'm using angularjs and it took me some time to find out how to copy an object to another object. Normally you'll get an objects clone by calling clone or here in angular copy:
var targetObj = angular.copy(sourceObj);
This gives you a new cloned instance (with a new reference) of the source object. But a quick look into the docs reveals the second parameter of copy:
angular.copy(sourceObj, targetObj)
This way you can override a target object with the fields and methods of the source and also keep the target objects reference.
Answer from schmijos on Stack OverflowI'm using angularjs and it took me some time to find out how to copy an object to another object. Normally you'll get an objects clone by calling clone or here in angular copy:
var targetObj = angular.copy(sourceObj);
This gives you a new cloned instance (with a new reference) of the source object. But a quick look into the docs reveals the second parameter of copy:
angular.copy(sourceObj, targetObj)
This way you can override a target object with the fields and methods of the source and also keep the target objects reference.
In JavaScript objects are passed by reference, never by value. So:
var objDemo, objDemoBackup;
objDemo = {
sub_1: "foo";
};
objDemoBackup = objDemo;
objDemo.sub_2 = "bar";
console.log(objDemoBackup.sub_2); // "bar"
To get a copy, you must use a copy function. JavaScript doesn't have one natively but here is a clone implementation: How do I correctly clone a JavaScript object?
var objDemo, objDemoBackup;
objDemo = {
sub_1: "foo";
};
objDemoBackup = clone(objDemo);
objDemo.sub_2 = "bar";
console.log(objDemoBackup.sub_2); // undefined
How do you replace an Object value in Javascript? - Stack Overflow
javascript - Replacing objects in array - Stack Overflow
How to replace object key value by another key value in the same object ?
let newlist = list.map(e => ({...e, name: e.nationality}) )-
eis for "element", where the.mapmethod touches each element in a source array, and then returns a new array. -
newlistwill have your modified array.listremains unchanged. -
e =>begins an "arrow function". I want to return an object, but objects require curly braces, just like a function body. Defining an object{}and wrapping it in()sentinels tells JS that "these curlies are not a function body" -
without a function body, the "arrow function" expects a statement which it will then return by default without specifically using
returnkeyword. -
...edoes a js "spread" on theevariable. It takes the entire contents ofeand puts them right there as part of the new object. It then replaces the contents of thenameproperty with data from the current element.
The long way:
let newlist = list.map(function (element) {
element.name = element.nationality
return element
}) More on reddit.com javascript - Replace array of objects with new object - Stack Overflow
Use the "findIndex" method to look for the index of the new item element in the rows array. Afterwards, check if a result was found (check if the index is greater than -1). Assign the item to the array using the position of the found element.
const indexOfItemInArray = rows.findIndex(q => q.id === new_item.id);
if (indexOfItemInArray > -1) {
rows[indexOfItemInArray] = new_item;
}
Or use the "splice" method:
const indexOfItemInArray = rows.findIndex(q => q.id === new_item.id);
rows.splice(indexOfItemInArray, 1, new_item);
To update easilly your array with a new value for specific id, use the map function :
rows = rows.map((row) => {
if (row.id === new_item.id) {
row = new_item;
}
return row;
});
To comply with the request
Create a function called changeEmail that takes in a user object and a newEmail string
your changeEmail function signature should look like
function changeEmail(userObject, emailString) {
}
Replace the user's current email address (assigned to the email property) with the newEmail string
means your function body could then look something like:
userObject.email = emailString;
and finally
then return the updated user object
would be
return userObject;
I think youre overcomplicating it. You just need to update the property:
function changeEmail(user,email){
user.email = email;
return user;
}
So you can do:
changeEmail({email:"before"},"after");
If you wanna annoy your teacher with some ESnext:
const changeEmail = (user,email)=>({...user,email});
//(note this does shallow copy)
const user = changeEmail({email:"before"},"after");
And actually, i think this assignment isnt really useful. Why not simply:
user.email = "after";
You can use Array#map with Array#find.
arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);
Show code snippet
var arr1 = [{
id: '124',
name: 'qqq'
}, {
id: '589',
name: 'www'
}, {
id: '45',
name: 'eee'
}, {
id: '567',
name: 'rrr'
}];
var arr2 = [{
id: '124',
name: 'ttt'
}, {
id: '45',
name: 'yyy'
}];
var res = arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);
console.log(res);
Run code snippetEdit code snippet Hide Results Copy to answer Expand
Here, arr2.find(o => o.id === obj.id) will return the element i.e. object from arr2 if the id is found in the arr2. If not, then the same element in arr1 i.e. obj is returned.
There is always going to be a good debate on time vs space, however these days I've found using space is better for the long run.. Mathematics aside let look at a one practical approach to the problem using hashmaps, dictionaries, or associative array's whatever you feel like labeling the simple data structure..
var marr2 = new Map(arr2.map(e => [e.id, e]));
arr1.map(obj => marr2.has(obj.id) ? marr2.get(obj.id) : obj);
I like this approach because though you could argue with an array with low numbers you are wasting space because an inline approach like @Tushar approach performs indistinguishably close to this method. However I ran some tests and the graph shows how performant in ms both methods perform from n 0 - 1000. You can decide which method works best for you, for your situation but in my experience users don't care to much about small space but they do care about small speed.

Here is my performance test I ran for source of data
var n = 1000;
var graph = new Array();
for( var x = 0; x < n; x++){
var arr1s = [...Array(x).keys()];
var arr2s = arr1s.filter( e => Math.random() > .5);
var arr1 = arr1s.map(e => {return {id: e, name: 'bill'}});
var arr2 = arr2s.map(e => {return {id: e, name: 'larry'}});
// Map 1
performance.mark('p1s');
var marr2 = new Map(arr2.map(e => [e.id, e]));
arr1.map(obj => marr2.has(obj.id) ? marr2.get(obj.id) : obj);
performance.mark('p1e');
// Map 2
performance.mark('p2s');
arr1.map(obj => arr2.find(o => o.id === obj.id) || obj);
performance.mark('p2e');
graph.push({ x: x, r1: performance.measure('HashMap Method', 'p1s', 'p1e').duration, r2: performance.measure('Inner Find', 'p2s','p2e').duration});
}
Hello
I would like to change the the value of name by nationality in the object array bellow
How to to it?
let newlist = list.map(e => ({...e, name: e.nationality}) )
-
eis for "element", where the.mapmethod touches each element in a source array, and then returns a new array. -
newlistwill have your modified array.listremains unchanged. -
e =>begins an "arrow function". I want to return an object, but objects require curly braces, just like a function body. Defining an object{}and wrapping it in()sentinels tells JS that "these curlies are not a function body" -
without a function body, the "arrow function" expects a statement which it will then return by default without specifically using
returnkeyword. -
...edoes a js "spread" on theevariable. It takes the entire contents ofeand puts them right there as part of the new object. It then replaces the contents of thenameproperty with data from the current element.
The long way:
let newlist = list.map(function (element) {
element.name = element.nationality
return element
})
If you don't want a new array, then .forEach, and add a new key with the value of the name, then delete name.
If you want a new array, then .map and you can for example create a new item object with the needed keys. This can be done in many ways.
You don't need the fancy splice logic. Just set the array element and forget it.
const sampleArray = [{ id: 'price' }, { id: 'hotel1', filters: [] }, { id: 'type' }]
const index = sampleArray.findIndex((obj) => obj.id === 'hotel1'); // find index
sampleArray[index] = { id: 'hotel2' }; // replace with new object ... working :)
console.log(JSON.stringify(sampleArray));
You can use the map() function:
const updatedArray = sampleArray.map(item => item.id === 'hotel' ? {...item, id: 'hotel2'} : item);
Since you already record the index of all the objects in the array (including the active one), you can just get the edits of the user and store them in an obj and create a new obj merging the edits with activeObj:
const edittedObj = Object.assign(activeObj, edits) // creates new obj with applied edits
this.arrayOfObjects.splice(activeObj.dnd.index, 1, edittedObj) // puts editted obj into array
Since you have an array of objects, you can set your active item to one of the objects, and that variable will be a reference to the object in the array. For example:
var array = [{a: 1, b: 2, c: 3}, {x: 1}, {x: 2}];
console.log(array[0]); // {a: 1, b: 2, c: 3}
var activeItem = array[0];
activeItem.a = 99;
console.log(array[0]); // {a: 99, b: 2, c: 3}
That way, writing the properties of activeItem writes the properties to the correct item in your array of objects.
delete everything from the old object, and then add new properties, key-by-key:
function modify(obj, newObj) {
Object.keys(obj).forEach(function(key) {
delete obj[key];
});
Object.keys(newObj).forEach(function(key) {
obj[key] = newObj[key];
});
}
var x = {a:1}
modify(x, {b:42})
document.write(JSON.stringify(x));
If you're wondering whether it's a good idea in general, the answer is no. Construct a new object, return it from the function and assign - this is a much preferred way.
You can achieve this (not exactly what you want) if you wrap your object and change the modify function like this,
var wrapper = {};
wrapper.x = {a:1};
function modify(obj, key) {
obj[key] = {b:2};
}
modify(wrapper, 'x');
console.log(wrapper.x); // {b:2}
Using ES7+ syntax and a functional approach:
const new_obj = { ...obj, name: { first: 'blah', last: 'ha'} }
On recent browsers with ECMAScript 2015, you can do:
Object.assign(skillet.person.name, { first: 'blah', last: 'ha'});
which will preserve any existing attribute not listed in the right object.
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign
[EDIT] With ES7, you can do even shorter, but it recreates the object (unlike Object.assign) and then adds some overhead if you care about performance. (comment thanks to Jamie Marshall)
{...skillet.person.name, ...{ first: 'blah', last: 'ha'}};
Reference: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax