admin管理员组文章数量:1134589
How can I copy every element of an array (where the elements are objects), into another array, so that they are totally independent?
I don't want changing an element in one array to affect the other.
How can I copy every element of an array (where the elements are objects), into another array, so that they are totally independent?
I don't want changing an element in one array to affect the other.
Share Improve this question edited Apr 28, 2022 at 22:12 Alexander Abakumov 14.5k16 gold badges96 silver badges132 bronze badges asked Apr 26, 2013 at 9:20 hAlEhAlE 1,2933 gold badges13 silver badges19 bronze badges 2 |8 Answers
Reset to default 121The key things here are
- The entries in the array are objects, and
- You don't want modifications to an object in one array to show up in the other array.
That means we need to not just copy the objects to a new array (or a target array), but also create copies of the objects.
If the destination array doesn't exist yet...
...use map
to create a new array, and copy the objects as you go:
const newArray = sourceArray.map(obj => /*...create and return copy of `obj`...*/);
...where the copy operation is whatever way you prefer to copy objects, which varies tremendously project to project based on use case. That topic is covered in depth in the answers to this question. But for instance, if you only want to copy the objects but not any objects their properties refer to, you could use spread notation (ES2015+):
const newArray = sourceArray.map(obj => ({...obj}));
That does a shallow copy of each object (and of the array). Again, for deep copies, see the answers to the question linked above.
Here's an example using a naive form of deep copy that doesn't try to handle edge cases, see that linked question for edge cases:
function naiveDeepCopy(obj) {
const newObj = {};
for (const key of Object.getOwnPropertyNames(obj)) {
const value = obj[key];
if (value && typeof value === "object") {
newObj[key] = {...value};
} else {
newObj[key] = value;
}
}
return newObj;
}
const sourceArray = [
{
name: "joe",
address: {
line1: "1 Manor Road",
line2: "Somewhere",
city: "St Louis",
state: "Missouri",
country: "USA",
},
},
{
name: "mohammed",
address: {
line1: "1 Kings Road",
city: "London",
country: "UK",
},
},
{
name: "shu-yo",
},
];
const newArray = sourceArray.map(naiveDeepCopy);
// Modify the first one and its sub-object
newArray[0].name = newArray[0].name.toLocaleUpperCase();
newArray[0].address.country = "United States of America";
console.log("Original:", sourceArray);
console.log("Copy:", newArray);
.as-console-wrapper {
max-height: 100% !important;
}
If the destination array exists...
...and you want to append the contents of the source array to it, you can use push
and a loop:
for (const obj of sourceArray) {
destinationArray.push(copy(obj));
}
Sometimes people really want a "one liner," even if there's no particular reason for it. If you refer that, you could create a new array and then use spread notation to expand it into a single push
call:
destinationArray.push(...sourceArray.map(obj => copy(obj)));
Easy way to get this working is using:
var cloneArray = JSON.parse(JSON.stringify(originalArray));
I have issues with getting arr.concat()
or arr.splice(0)
to give a deep copy. Above snippet works perfectly.
A great way for cloning an array is with an array literal and the spread syntax. This is made possible by ES2015.
const objArray = [{name:'first'}, {name:'second'}, {name:'third'}, {name:'fourth'}];
const clonedArr = [...objArray];
console.log(clonedArr) // [Object, Object, Object, Object]
You can find this copy option in MDN's documentation: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator#Copy_an_array
It is also an Airbnb's best practice. https://github.com/airbnb/javascript#es6-array-spreads
Note: The spread syntax in ES2015 goes one level deep while copying an array. Therefore, they are unsuitable for copying multidimensional arrays.
var clonedArray = array.concat();
If you want to keep reference:
Array.prototype.push.apply(destinationArray, sourceArray);
There are two important notes.
- Using
array.concat()
does not work using Angular 1.4.4 and jQuery 3.2.1 (this is my environment). - The
array.slice(0)
is an object. So if you do something likenewArray1 = oldArray.slice(0); newArray2 = oldArray.slice(0)
, the two new arrays will reference to just 1 array and changing one will affect the other.
Alternatively, using newArray1 = JSON.parse(JSON.stringify(old array))
will only copy the value, thus it creates a new array each time.
I suggest using concat()
if you are using nodeJS. In all other cases, I have found that slice(0)
works fine.
structuredClone
represents a novel approach to perform deep cloning.
const objArray = [{name:'first'}, {name:'second'}, {name:'third'}, {name:'fourth'}];
// Clone it
const clonedArr = structuredClone(objArray);
console.log(clonedArr)
本文标签: javascriptHow to copy all items from one array into anotherStack Overflow
版权声明:本文标题:javascript - How to copy all items from one array into another? - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736860442a1955889.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
a = [1, 2, 3], b = [4, 5, 6]
. If you doa = b.slice()
you have copied b. You have not copied the values of b into a. a's array may be referenced multiple places. – user128511 Commented Jul 8, 2022 at 5:09