Copy array by value
Use this:
let oldArray = [1, 2, 3, 4, 5];
let newArray = oldArray.slice();
console.log({newArray});
Cloning an array with its content
You need to do a deep copy of your array.
Here is the way to do it
Marshal.load(Marshal.dump(a))
This is because you are cloning the array but not the elements inside. So the array object is different but the elements it contains are the same instances. You could, for example, also do a.each{|e| b << e.dup}
for your case
How do you clone an array of objects in JavaScript?
Creating a deep copy with structuredClone
The modern way to deep copy an array in JavaScript is to use structuredClone:
array2 = structuredClone(array1);
However, this function is relatively new (Chrome 98, Firefox 94) and is currently only available to about 85% of users, so it's not ready for production yet without a polyfill.
As an alternative, you can use one of the well-supported JSON-based solutions below.
Creating a deep copy with JSON.parse
A general solution, that accounts for all possible objects inside an Array of objects may not be possible.
That said, if your array contains objects that have JSON-serializable content (no functions, no Number.POSITIVE_INFINITY
, etc.) one simple way to avoid loops, at a performance cost, is this pure vanilla one-line solution.
let clonedArray = JSON.parse(JSON.stringify(nodesArray))
To summarize the comments below, the primary advantage of this approach is that it also clones the contents of the array, not just the array itself. The primary downsides are its limit of only working on JSON-serializable content, and it's performance is ~30 times slower than the spread method.
If you have shallow objects in the array, and IE6 is acceptable, a better approach is to use the spread operator combined with the .map array operator. For a two levels deep situation (like the array in the Appendix below):
clonedArray = nodesArray.map(a => {return {...a}})
The reasons are two fold: 1) It is much, much faster (see below for a benchmark comparison) and it will also allow any valid object in your array.
*Appendix:
The performance quantification is based on cloning this array of objects a million times:
[{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic1.jpg?raw=true', id: '1', isFavorite: false}, {url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic2.jpg?raw=true', id: '2', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic3.jpg?raw=true', id: '3', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic4.jpg?raw=true', id: '4', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic5.jpg?raw=true', id: '5', isFavorite: true},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic6.jpg?raw=true', id: '6', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic7.jpg?raw=true', id: '7', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic8.jpg?raw=true', id: '8', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic9.jpg?raw=true', id: '9', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic10.jpg?raw=true', id: '10', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic11.jpg?raw=true', id: '11', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic12.jpg?raw=true', id: '12', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic13.jpg?raw=true', id: '13', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic14.jpg?raw=true', id: '14', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic15.jpg?raw=true', id: '15', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic16.jpg?raw=true', id: '16', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic17.jpg?raw=true', id: '17', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic18.jpg?raw=true', id: '18', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic19.jpg?raw=true', id: '19', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic20.jpg?raw=true', id: '20', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic21.jpg?raw=true', id: '21', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic22.jpg?raw=true', id: '22', isFavorite: false},{url: 'https://github.com/bobziroll/scrimba-react-bootcamp-images/blob/master/pic23.jpg?raw=true', id: '23', isFavorite: false}]
either using:
let clonedArray = JSON.parse(JSON.stringify(nodesArray))
or:
clonedArray = nodesArray.map(a => {return {...a}})
The map/spread approach took 0.000466 ms per pass and the JSON.parse and JSON.stringify 0.014771 ms per pass.*
Fastest way to duplicate an array in JavaScript - slice vs. 'for' loop
There are at least 6 (!) ways to clone an array:
- loop
- slice
- Array.from()
- concat
- spread operator (FASTEST)
- map
A.map(function(e){return e;});
There has been a huuuge BENCHMARKS thread, providing following information:
for blink browsers
slice()
is the fastest method,concat()
is a bit slower, andwhile loop
is 2.4x slower.for other browsers
while loop
is the fastest method, since those browsers don't have internal optimizations forslice
andconcat
.
This remains true in Jul 2016.
Below are simple scripts that you can copy-paste into your browser's console and run several times to see the picture. They output milliseconds, lower is better.
while loop
n = 1000*1000;
start = + new Date();
a = Array(n);
b = Array(n);
i = a.length;
while(i--) b[i] = a[i];
console.log(new Date() - start);
slice
n = 1000*1000;
start = + new Date();
a = Array(n);
b = a.slice();
console.log(new Date() - start);
Please note that these methods will clone the Array object itself, array contents however are copied by reference and are not deep cloned.
origAr == clonedArr //returns false
origAr[0] == clonedArr[0] //returns true
Cloning an array in Javascript/Typescript
Clone an object:
const myClonedObject = Object.assign({}, myObject);
Clone an Array:
- Option 1 if you have an array of primitive types:
const myClonedArray = Object.assign([], myArray);
- Option 2 - if you have an array of objects:
const myArray= [{ a: 'a', b: 'b' }, { a: 'c', b: 'd' }];
const myClonedArray = [];
myArray.forEach(val => myClonedArray.push(Object.assign({}, val)));
(Array.Clone) Shallow Copy vs Deep Copy of an Array
A Shallow Copy of an Array is not the same as a copy of an array:
- Copying an array, copies the reference to the array to a new variable. Both variables will be pointing to the same values.
- The
Clone
method creates a new, distinct array containing a copy of the elements of the original array. If those elements are value types (like in your caseìnt
) the new array will contain the same set of values as the original but stored in another location.
If the elements of the array are of a reference type, the new array will contain copies of the original references. So the first elements of both array would contain the same reference to an object.
See also: https://learn.microsoft.com/en-us/dotnet/api/system.array.clone?view=net-6.0
A shallow copy of an Array copies only the elements of the Array, whether they are reference types or value types, but it does not copy the objects that the references refer to. The references in the new Array point to the same objects that the references in the original Array point to.
Copying of an array of objects to another Array without object reference in javascript(Deep copy)
Let me understand: you don't want just have a new array, but you want to create a new instance for all objects are present in the array itself? So if you modify one of the objects in the temp array, that changes is not propagated to the main array?
If it's the case, it depends by the values you're keeping in the main array. If these objects are simple objects, and they can be serialized in JSON, then the quickest way is:
var tempArray = JSON.parse(JSON.stringify(mainArray));
If you have more complex objects (like instances created by some your own constructors, html nodes, etc) then you need an approach ad hoc.
Edit:
If you don't have any methods on your newObjectCreation
, you could use JSON
, however the constructor won't be the same. Otherwise you have to do the copy manually:
var tempArray = [];
for (var i = 0, item; item = mainArray[i++];) {
tempArray[i] = new newObjectCreation(item.localIP, item.remoteIP, item.areaId);
}
How to copy all items from one array into another?
The 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;
}
How to clone an array and push new value in a chain?
array.push
returns the new length of the array which you're storing in arr2
variable.
You need the following:
var arr1 = ["foo", "bar"];
var arr2 = arr1.concat("moo");
console.log(arr2);
Related Topics
Why Does Psych Yaml Interpreter Add Line Breaks Around 80 Characters
Check If the Sum of Two Different Numbers in an Array Equal a Variable Number
Phonegap and Rails 3: How to Interact with a Rails 3 App
How to Have One Resource in Routes for Namespace and Root Path Altogether - Rails 4
Using Rest-Client to Download a File to Disk Without Loading It All in Memory First
Devise Not Working Well with Multiple Subdomains on Ror3 Application
Ruby on Rails - Generating Bit.Ly Style Identifiers
What Purpose Can Anonymous Modules Serve
Ruby Gem Installation Error After Osx Yosemite and Xcode 6 Installation
How to Export a Rails Model to JSON Schema
How to Get Class-Object from String "A::B::C" in Ruby
Using Ruby CSV to Extract One Column
Form_For with Multiple Controller Actions for Submit
Generating Sequential Numbers in Multi-User Saas Application
Sass: Dealing with The Ie 4095 Selectors Per Stylesheet Restriction