Copying an array of objects into another array in javascript

自古美人都是妖i 提交于 2019-11-28 04:28:40

If the destination array doesn't exist yet...

...you can use slice() or concat(). slice() is probably more idiomatic (you'll also see slice(0), but the default is 0, so...):

var destinationArray = sourceArray.slice(); // Probably more idiomatic
// or
var destinationArray = sourceArray.concat();

As of ES2015 (aka ES6), there's also Array.from, which creates a new array from any array-like thing (including an actual array):

var destinationArray = Array.from(sourceArray);

(Array.from can be shimmed/polyfilled for older JavaScript engines.)

Also as of ES2015, you can use iterable spread notation and an array literal with any iterable (including an array):

var destinationArray = [...sourceArray];

After that, both arrays will have the same contents. Changing one array will not change the other. Naturally, if an array entry is an object, the entry for that object in both arrays will point to the same object; this isn't a "deep" copy.

If the destination array exists...

...and you want to append the contents of the source array to it, you can use push:

destinationArray.push.apply(destinationArray, sourceArray);

That works by calling push on the destination array using the apply feature of JavaScript functions, which lets you specify the arguments for the function call as an array. push will push as many elements as it has arguments, so it ends up copying the elements from the source array to the destination array.

In ES2015 and later, you can make that cleaner with iterable spread notation (...):

destinationArray.push(...sourceArray);

Note that in both cases, the call is limited by the JavaScript engine's maximum number of function arguments (as of this writing, that's at least in the thousands for all major engines [and not in the hundreds of thousands, at least not for Chrome's V8]).

Here's an ES5 version:

var source1, dest1, source2, dest2;

snippet.log("If dest doesn't exist yet:");
source1 = [1, 2, 3, 4];
dest1 = source1.slice(0);
snippet.log("[before change] source1 = " + source1.join(", "));
snippet.log("[before change] dest1 = " + dest1.join(", "));
source1[2] = "three";
dest1[3] = "four";
snippet.log("[after change] source1 = " + source1.join(", "));
snippet.log("[after change] dest1 = " + dest1.join(", "));

snippet.log("If dest already exists and we're just appending:");
source2 = [1, 2, 3, 4];
dest2 = ['a', 'b', 'c', 'd'];
snippet.log("[before append] source2 = " + source2.join(", "));
snippet.log("[before append] dest2 = " + dest2.join(", "));
dest2.push.apply(dest2, source2);
snippet.log("[before change] source2 = " + source2.join(", "));
snippet.log("[before change] dest2 = " + dest2.join(", "));
source2[2] = "three";
dest2[7] = "four";
snippet.log("[after change] source2 = " + source2.join(", "));
snippet.log("[after change] dest2 = " + dest2.join(", "));
<!-- Script provides the `snippet` object, see http://meta.stackexchange.com/a/242144/134069 -->
<script src="//tjcrowder.github.io/simple-snippets-console/snippet.js"></script>

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 operator. This is made possible by ES2015.

let objArray = [{name:'first'}, {name:'second'}, {name:'third'}, {name:'fourth'}];

let clonedArr = [...objArray];

console.log(clonedArr) // [Object, Object, Object, Object]

You can find this copy option in MDN's documentation for spread operators 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: Typically the spread operators 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);

Tran Vu Dang Khoa

There are two important notes.

  1. Using array.concat() does not work using Angular 1.4.4 and jQuery 3.2.1 (this is my environment).
  2. The array.slice(0) is an object. So if you do something like newArray1 = 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.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!