I wanted to generate new two-dimensional arrays from a existing 2D array and then change the value of some elements of the new array but whenever I try to modify the array content it is showing changes to all the generated arrays (which means they all have the same reference).Please ,help me to find my error and provide relevant methods and concepts to create the new 2D arrays
Another question is why the testing for loop returns "No error" while they are still equal
I am still a beginner in javascript.So any help will be much appreciated.Thanks in advance
My Code is at http://jsbin.com/miqapupopa/edit?js,console
This is my code:
var a=[[1,0,0],[0,0,0],[0,0,0]];var big_arr=[a];var c=-1;
//function f(){this.objarr = a.map(function(val){return val;}) ;};
for(var i=0;i<3;i++){
for(var j=0;j<3;j++){
var arr=a.map(function(val){return val;}) ;
if(a[i][j]===0){
arr[i][j]=c;
big_arr.push(arr);}
continue;
} c=(c===1)?-1:1;console.log(c);
}console.log(big_arr,a);
for(var i=0;i<9;i++){
console.log(big_arr[i]);
}
//just checking if all arrays are equal
for(var k=0;k<9;k++){
if(big_arr[k]==a) console.log("error"); //toString works
else console.log("No error");}
//output should be obj=[[[1,0,0],[0,0,0],[0,0,0]],[[1,1,0],[0,0,0],[0,0,0]],[[1,0,1],[0,0,0],[0,0,0]],[[1,0,0],[-1,0,0],[0,0,0]],[[1,0,0],[0,-1,0],[0,0,0]],[[1,0,0],[0,0,-1],[0,0,0]],[[1,0,0],[0,0,0],[1,0,0]],[[1,0,0],[0,0,0],[0,1,0]][[1,0,0],[0,0,0],[0,0,1]]]
OK to clone an N dimensional array let's invent a generic Array method. Array.prototype.clone()
Array.prototype.clone = function(){
return this.reduce((p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p),[])
}
var arr = [[1,2,3],[4,5,6],[7,8,9]],
brr = arr.clone();
brr[0][1] = 11;
brr[2][2] = 55;
arr[1][1] = 42;
console.log(JSON.stringify(arr));
console.log(JSON.stringify(brr));
The above code is utilizing reduce method to generate a clone of a multi-dimensional array. It is a recursive function. In this example reduce takes two arguments. 1) A a callback function 2) An initial parameter.
Callback function: (p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p) is actually
function(p,c,i) {
if (Array.isArray(c)) {
p[i] = c.clone(); // recursive cloning call with inner array item
} else {
p[i] = c;
}
return p;
}
Initial Parameter: An initial value provided for p to start with. In this case it is an empty array ([]).
Actually in the comments Thomas has given a map version of the very same code. You may chose to use that one too.
And then if you would like to instantiate an ND array from scratch and fill it witn an initial value you will definitelly need the above cloning utility. Lets do...
Array.prototype.clone = function(){
return this.reduce((p,c,i) => (p[i] = Array.isArray(c) ? c.clone() : c, p),[])
}
function arrayND(...n){
return n.reduceRight((p,c) => c = (new Array(c)).fill(true).map(e => Array.isArray(p) ? p.clone() : p ));
}
var arr = arrayND(...[6,6,6],8); //last argument is the initializing value
arr[1][3][5] = "eight";
console.log(JSON.stringify(arr));
Related
I want to filter a array by keeping the same array without creating a new one.
with Array.filter() :
getFiltersConfig() {
return this.config.filter((topLevelConfig) => topLevelConfig.name !== 'origin')
}
what is the best way to get the same result by filtering by value without returning a new array ?
For completeness, I thought it might make sense to show a mutated array variant.
Below is a snippet with a simple function mutationFilter, this will filter the array directly, notice in this function the loop goes in reverse, this is a technique for deleting items with a mutated array.
Also a couple of tests to show how Array.filter creates a new array, and mutationFilter does not.
Although in most cases creating a new array with Array.filter is normally what you want. One advantage of using a mutated array, is that you can pass the array by reference, without you would need to wrap the array inside another object. Another advantage of course is memory, if your array was huge, inline filtering would take less memory.
let arr = ['a','b','a'];
let ref = arr; //keep reference of original arr
function mutationFilter(arr, cb) {
for (let l = arr.length - 1; l >= 0; l -= 1) {
if (!cb(arr[l])) arr.splice(l, 1);
}
}
const cond = x => x !== 'a';
const filtered = arr.filter(cond);
mutationFilter(arr, cond);
console.log(`ref === array -> ${ref === arr}`);
console.log(arr);
console.log(`ref === filtered -> ${ref === filtered}`);
console.log(filtered);
I want to filter a array by keeping the same array without creating a new one.
what is the best way to get the same result by filtering by value without returning a new array ?
I have an answer for the second criterion, but violates the first. I suspect that you may want to "not create a new one" specifically because you only want to preserve the reference to the array, not because you don't want to create a new array, necessarily (e.g. for memory concerns).
What you could do is create a temp array of what you want
var temp = this.config.filter((topLevelConfig) => topLevelConfig.name !== 'origin')
Then set the length of the original array to 0 and push.apply() the values "in-place"
this.config.length = 0; //clears the array
this.config.push.apply(this.config, temp); //adds what you want to the array of the same reference
You could define you custom method like so:
if(!Array.prototype.filterThis){
Array.prototype.filterThis = function (callBack){
if(typeof callBack !== 'function')
throw new TypeError('Argument must of type <function>');
let t = [...this];
this.length = 0;
for(let e of t) if(callBack(e)) this.push(e);
return this;
}
}
let a = [1,2,3,4,5,5,1,5];
a.filterThis(x=>x!=5);
console.log(a);
Warning: Be very cautious in altering built in prototypes. I would even say unless your making a polyfill don't touch. The errors it can cause can be very subtle and very hard to debug.
Not sure why would you want to do mutation but if you really want to do it, maybe assign it back to itself?
let arr = ['a','b','a'];
arr = arr.filter(x => x !== 'a');
console.log(arr)
I am trying to solve a problem which states to remove(delete) the smallest number in an array without the order of the elements to the left of the smallest element getting changed . My code is -:
function removeSmallest(numbers){
var x = Math.min.apply(null,numbers);
var y = numbers.indexOf(x);
numbers.splice(y,1);
return numbers;
}
It is strictly given in the instructions not to mutate the original array/list. But I am getting an error stating that you have mutated original array/list .
How do I remove the error?
Listen Do not use SPLICE here. There is great known mistake rookies and expert do when they use splice and slice interchangeably without keeping the effects in mind.
SPLICE will mutate original array while SLICE will shallow copy the original array and return the portion of array upon given conditions.
Here Slice will create a new array
const slicedArray = numbers.slice()
const result = slicedArray.splice(y,1);
and You get the result without mutating original array.
first create a copy of the array using slice, then splice that
function removeSmallest(numbers){
var x = Math.min.apply(null,numbers);
var y = numbers.indexOf(x);
return numbers.slice().splice(y,1);
}
You can create a shallow copy of the array to avoid mutation.
function removeSmallest(numbers){
const newNumbers = [...numbers];
var x = Math.min.apply(null,newNumbers);
var y = newNumbers.indexOf(x);
newNumbers.splice(y,1);
return newNumbers;
}
array.slice() and [... array] will make a shallow copy of your array object.
"shallow" the word says itself.
in my opinion, for copying your array object the solution is:
var array_copy = copy(array);
// copy function
function copy(object) {
var output, value, key;
output = Array.isArray(object) ? [] : {};
for (key in object) {
value = object[key];
output[key] = (typeof value === "object") ? copy(value) : value;
}
return output;
}
Update
Alternative solution is:-
var arr_copy = JSON.parse(JSON.stringify(arr));
I'm not sure what the exact context of the problem is, but the goal might be to learn to write pure transformations of data, rather than to learn how to copy arrays. If this is the case, using splice after making a throwaway copy of the array might not cut it.
An approach that mutates neither the original array nor a copy of it might look like this: determine the index of the minimum element of an array, then return the concatenation of the two sublists to the right and left of that point:
const minIndex = arr =>
arr.reduce(
(p, c, i) => (p === undefined ? i : c < arr[p] ? i : p),
undefined
);
const removeMin = arr => {
const i = minIndex(arr);
return minIndex === undefined
? arr
: [...arr.slice(0, i), ...arr.slice(i + 1)];
};
console.log(removeMin([1, 5, 6, 0, 11]));
Let's focus on how to avoid mutating. (I hope when you say "remove an error" you don't mean "suppress the error message" or something like that)
There are many different methods on Array.prototype and most don't mutate the array but return a new Array as a result. say .map, .slice, .filter, .reduce
Telling the truth just a few mutate (like .splice)
So depending on what your additional requirements are you may find, say .filter useful
let newArray = oldArray.filter(el => el !== minimalElementValue);
or .map
let newArray = oldArray.map(el => el === minimalElementValue? undefined: el);
For sure, they are not equal but both don't mutate the original variable
I am learning map & reduce, but am having a hard time understanding how to utilize these methods to tackle problems.
For example,
Create a function that takes a number and returns an array of strings containing the number cut off at each digit.
420 should return ["4", "42", "420"]
My old Approach:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
var output = [];
for(var i = numArr.length-1; i>=0; i--) {
output.unshift(numArr.join('');
numArr.pop();
}
return output;
}
Attempt to use map-reduce combination:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
return numArr.map(function(element) {
var newElement = numArr.reduce(function(acc, val) {
return acc + val;
});
numArr.splice(element, 1);
return newElement;
});
}
You have used two loops, but apparently it can be done just with one.
function n(num) {
let res = (""+num).split('').map((_,i) => (""+num).slice(0, i+1));
return res;
}
console.log(n(420));
console.log(n(13579));
One-liner.
const n = num => (""+num).split('').map((_,i) => (""+num).slice(0, i+1));
console.log(n(420));
console.log(n(13579));
As others noted, that this problem doesn't seem to be the best use case of the map and reduce functions.
map function provides the element, index and array information in the parameters. Making use of these you can iterate on the elements you need to apply the reduce function.
Statement var arrayToIterate = arr.slice(0,i+1); helps to achieve the above mentioned array to iterate.
Complete Code:
function createArrayOfTiers(num) {
var numArr = num.toString().split('');
return numArr.map(function(element, i, arr) {
var arrayToIterate = arr.slice(0,i+1);
var newElement = arrayToIterate.reduce(function(acc, val) {
return acc + val;
},"");
return newElement;
});
}
var result = createArrayOfTiers(420);
console.log(result);
I don't think these are good uses-cases of map or reduce, but here goes :
var numArr = [4,2,0];
var result = numArr.map(e => numArr.join('')) // now ["420", "420", "420"]
.map((arr, i) => arr.substring(0, i+1)) // now ["4", "42", "420"]
console.log(result);
We first replace every element of the array by the whole (unmodified) array joined into a string, then substring each of these strings based on their position in the outer array.
There's a reduction hidden in there, although not using reduce : join reduces [4, 2, 0] to "420".
I am learning map & reduce, but am having a hard time understanding how to utilize these methods to tackle problems.
Mapping associates to each value of the source array a new value provided by a mapping function : if you have an [x, y, z] array, a mapping function f(x)=x+1, the result of mapping the array with the function will be [x+1, y+1, z+1].
I believe reduction was meant to "reduce" an array to a primitive type, although I might be mistaken. If you have an [x, y, z] array and reduce it with the addition operation, the result will be x+y+z.
I have a JavaScript array like this:
var myData=['237','124','255','124','366','255'];
I need the array elements to be unique and sorted:
myData[0]='124';
myData[1]='237';
myData[2]='255';
myData[3]='366';
Even though the members of array look like integers, they're not integers, since I have already converted each to be string:
var myData[0]=num.toString();
//...and so on.
Is there any way to do all of these tasks in JavaScript?
This is actually very simple. It is much easier to find unique values, if the values are sorted first:
function sort_unique(arr) {
if (arr.length === 0) return arr;
arr = arr.sort(function (a, b) { return a*1 - b*1; });
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) { //Start loop at 1: arr[0] can never be a duplicate
if (arr[i-1] !== arr[i]) {
ret.push(arr[i]);
}
}
return ret;
}
console.log(sort_unique(['237','124','255','124','366','255']));
//["124", "237", "255", "366"]
You can now achieve the result in just one line of code.
Using new Set to reduce the array to unique set of values.
Apply the sort method after to order the string values.
var myData=['237','124','255','124','366','255']
var uniqueAndSorted = [...new Set(myData)].sort()
UPDATED for newer methods introduced in JavaScript since time of question.
This might be adequate in circumstances where you can't define the function in advance (like in a bookmarklet):
myData.sort().filter(function(el,i,a){return i===a.indexOf(el)})
Here's my (more modern) approach using Array.protoype.reduce():
[2, 1, 2, 3].reduce((a, x) => a.includes(x) ? a : [...a, x], []).sort()
// returns [1, 2, 3]
Edit: More performant version as pointed out in the comments:
arr.sort().filter((x, i, a) => !i || x != a[i-1])
function sort_unique(arr) {
return arr.sort().filter(function(el,i,a) {
return (i==a.indexOf(el));
});
}
How about:
array.sort().filter(function(elem, index, arr) {
return index == arr.length - 1 || arr[index + 1] != elem
})
This is similar to #loostro answer but instead of using indexOf which will reiterate the array for each element to verify that is the first found, it just checks that the next element is different than the current.
Try using an external library like underscore
var f = _.compose(_.uniq, function(array) {
return _.sortBy(array, _.identity);
});
var sortedUnique = f(array);
This relies on _.compose, _.uniq, _.sortBy, _.identity
See live example
What is it doing?
We want a function that takes an array and then returns a sorted array with the non-unique entries removed. This function needs to do two things, sorting and making the array unique.
This is a good job for composition, so we compose the unique & sort function together. _.uniq can just be applied on the array with one argument so it's just passed to _.compose
the _.sortBy function needs a sorting conditional functional. it expects a function that returns a value and the array will be sorted on that value. Since the value that we are ordering it by is the value in the array we can just pass the _.identity function.
We now have a composition of a function that (takes an array and returns a unique array) and a function that (takes an array and returns a sorted array, sorted by their values).
We simply apply the composition on the array and we have our uniquely sorted array.
This function doesn't fail for more than two duplicates values:
function unique(arr) {
var a = [];
var l = arr.length;
for(var i=0; i<l; i++) {
for(var j=i+1; j<l; j++) {
// If a[i] is found later in the array
if (arr[i] === arr[j])
j = ++i;
}
a.push(arr[i]);
}
return a;
};
Here is a simple one liner with O(N), no complicated loops necessary.
> Object.keys(['a', 'b', 'a'].reduce((l, r) => l[r] = l, {})).sort()
[ 'a', 'b' ]
Explanation
Original data set, assume its coming in from an external function
const data = ['a', 'b', 'a']
We want to group all the values onto an object as keys as the method of deduplication. So we use reduce with an object as the default value:
[].reduce(fn, {})
The next step is to create a reduce function which will put the values in the array onto the object. The end result is an object with a unique set of keys.
const reduced = data.reduce((l, r) => l[r] = l, {})
We set l[r] = l because in javascript the value of the assignment expression is returned when an assignment statement is used as an expression. l is the accumulator object and r is the key value. You can also use Object.assign(l, { [r]: (l[r] || 0) + 1 }) or something similar to get the count of each value if that was important to you.
Next we want to get the keys of that object
const keys = Object.keys(reduced)
Then simply use the built-in sort
console.log(keys.sort())
Which is the set of unique values of the original array, sorted
['a', 'b']
The solution in a more elegant way.
var myData=['237','124','255','124','366','255'];
console.log(Array.from(new Set(myData)).sort((a,b) => a - b));
I know the question is very old, but maybe someone will come in handy
A way to use a custom sort function
//func has to return 0 in the case in which they are equal
sort_unique = function(arr,func) {
func = func || function (a, b) {
return a*1 - b*1;
};
arr = arr.sort(func);
var ret = [arr[0]];
for (var i = 1; i < arr.length; i++) {
if (func(arr[i-1],arr[i]) != 0)
ret.push(arr[i]);
}
}
return ret;
}
Example: desc order for an array of objects
MyArray = sort_unique(MyArray , function(a,b){
return b.iterator_internal*1 - a.iterator_internal*1;
});
No redundant "return" array, no ECMA5 built-ins (I'm pretty sure!) and simple to read.
function removeDuplicates(target_array) {
target_array.sort();
var i = 0;
while(i < target_array.length) {
if(target_array[i] === target_array[i+1]) {
target_array.splice(i+1,1);
}
else {
i += 1;
}
}
return target_array;
}
I guess I'll post this answer for some variety. This technique for purging duplicates is something I picked up on for a project in Flash I'm currently working on about a month or so ago.
What you do is make an object and fill it with both a key and a value utilizing each array item. Since duplicate keys are discarded, duplicates are removed.
var nums = [1, 1, 2, 3, 3, 4, 5, 5, 6, 7, 7, 8, 9, 9, 10];
var newNums = purgeArray(nums);
function purgeArray(ar)
{
var obj = {};
var temp = [];
for(var i=0;i<ar.length;i++)
{
obj[ar[i]] = ar[i];
}
for (var item in obj)
{
temp.push(obj[item]);
}
return temp;
}
There's already 5 other answers, so I don't see a need to post a sorting function.
// Another way, that does not rearrange the original Array
// and spends a little less time handling duplicates.
function uniqueSort(arr, sortby){
var A1= arr.slice();
A1= typeof sortby== 'function'? A1.sort(sortby): A1.sort();
var last= A1.shift(), next, A2= [last];
while(A1.length){
next= A1.shift();
while(next=== last) next= A1.shift();
if(next!=undefined){
A2[A2.length]= next;
last= next;
}
}
return A2;
}
var myData= ['237','124','255','124','366','255','100','1000'];
uniqueSort(myData,function(a,b){return a-b})
// the ordinary sort() returns the same array as the number sort here,
// but some strings of digits do not sort so nicely numerical.
function sort() only is only good if your number has same digit, example:
var myData = ["3","11","1","2"]
will return;
var myData = ["1","11","2","3"]
and here improvement for function from mrmonkington
myData.sort().sort(function(a,b){return a - b;}).filter(function(el,i,a){if(i==a.indexOf(el) & el.length>0)return 1;return 0;})
the above function will also delete empty array and you can checkout the demo below
http://jsbin.com/ahojip/2/edit
O[N^2] solutions are bad, especially when the data is already sorted, there is no need to do two nested loops for removing duplicates. One loop and comparing to the previous element will work great.
A simple solution with O[] of sort() would suffice. My solution is:
function sortUnique(arr, compareFunction) {
let sorted = arr.sort(compareFunction);
let result = sorted.filter(compareFunction
? function(val, i, a) { return (i == 0 || compareFunction(a[i-1], val) != 0); }
: function(val, i, a) { return (i == 0 || a[i-1] !== val); }
);
return result;
}
BTW, can do something like this to have Array.sortUnique() method:
Array.prototype.sortUnique = function(compareFunction) {return sortUnique(this, compareFunction); }
Furthermore, sort() could be modified to remove second element if compare() function returns 0 (equal elements), though that code can become messy (need to revise loop boundaries in the flight). Besides, I stay away from making my own sort() functions in interpreted languages, since it will most certainly degrade the performance. So this addition is for the ECMA 2019+ consideration.
The fastest and simpleness way to do this task.
const N = Math.pow(8, 8)
let data = Array.from({length: N}, () => Math.floor(Math.random() * N))
let newData = {}
let len = data.length
// the magic
while (len--) {
newData[data[len]] = true
}
var array = [2,5,4,2,5,9,4,2,6,9,0,5,4,7,8];
var unique_array = [...new Set(array)]; // [ 2, 5, 4, 9, 6, 0, 7, 8 ]
var uniqueWithSorted = unique_array.sort();
console.log(uniqueWithSorted);
output = [ 0, 2, 4, 5, 6, 7, 8, 9 ]
Here, we used only Set for removing duplicity from the array and then used sort for sorting array in ascending order.
I'm afraid you can't combine these functions, ie. you gotta do something like this:-
myData.unique().sort();
Alternatively you can implement a kind of sortedset (as available in other languages) - which carries both the notion of sorting and removing duplicates, as you require.
Hope this helps.
References:-
Array.sort
Array.unique
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
What is the most efficient way to clone a JavaScript object?
I need to copy an (ordered, not associative) array of objects. I'm using jQuery. I initially tried
jquery.extend({}, myArray)
but, naturally, this gives me back an object, where I need an array (really love jquery.extend, by the way).
So, what's the best way to copy an array?
Since Array.slice() does not do deep copying, it is not suitable for multidimensional arrays:
var a =[[1], [2], [3]];
var b = a.slice();
b.shift().shift();
// a is now [[], [2], [3]]
Note that although I've used shift().shift() above, the point is just that b[0][0] contains a pointer to a[0][0] rather than a value.
Likewise delete(b[0][0]) also causes a[0][0] to be deleted and b[0][0]=99 also changes the value of a[0][0] to 99.
jQuery's extend method does perform a deep copy when a true value is passed as the initial argument:
var a =[[1], [2], [3]];
var b = $.extend(true, [], a);
b.shift().shift();
// a is still [[1], [2], [3]]
$.extend(true, [], [['a', ['c']], 'b'])
That should do it for you.
I realize you're looking for a "deep" copy of an array, but if you just have a single level array you can use this:
Copying a native JS Array is easy. Use the Array.slice() method which creates a copy of part/all of the array.
var foo = ['a','b','c','d','e'];
var bar = foo.slice();
now foo and bar are 5 member arrays of 'a','b','c','d','e'
of course bar is a copy, not a reference... so if you did this next...
bar.push('f');
alert('foo:' + foo.join(', '));
alert('bar:' + bar.join(', '));
you would now get:
foo:a, b, c, d, e
bar:a, b, c, d, e, f
Everything in JavaScript is pass by reference, so if you want a true deep copy of the objects in the array, the best method I can think of is to serialize the entire array to JSON and then de-serialize it back.
If you want to use pure JavaScript then try this:
var arr=["apple","ball","cat","dog"];
var narr=[];
for(var i=0;i<arr.length;i++){
narr.push(arr[i]);
}
alert(narr); //output: apple,ball,vat,dog
narr.push("elephant");
alert(arr); // output: apple,ball,vat,dog
alert(narr); // apple,ball,vat,dog,elephant
how about complex types?
when array contains objects... or any else
My variant:
Object.prototype.copy = function(){
var v_newObj = {};
for(v_i in this)
v_newObj[v_i] = (typeof this[v_i]).contains(/^(array|object)$/) ? this[v_i].copy() : this[v_i];
return v_newObj;
}
Array.prototype.copy = function(){
var v_newArr = [];
this.each(function(v_i){
v_newArr.push((typeof v_i).contains(/^(array|object)$/) ? v_i.copy() : v_i);
});
return v_newArr;
}
It's not final version, just an idea.
PS: method each and contains are prototypes also.
I've come across this "deep object copy" function that I've found handy for duplicating objects by value. It doesn't use jQuery, but it certainly is deep.
http://www.overset.com/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value/
I plan on releasing this code in the next version of jPaq, but until then, you can use this if your goal is to do a deep copy of arrays:
Array.prototype.clone = function(doDeepCopy) {
if(doDeepCopy) {
var encountered = [{
a : this,
b : []
}];
var item,
levels = [{a:this, b:encountered[0].b, i:0}],
level = 0,
i = 0,
len = this.length;
while(i < len) {
item = levels[level].a[i];
if(Object.prototype.toString.call(item) === "[object Array]") {
for(var j = encountered.length - 1; j >= 0; j--) {
if(encountered[j].a === item) {
levels[level].b.push(encountered[j].b);
break;
}
}
if(j < 0) {
encountered.push(j = {
a : item,
b : []
});
levels[level].b.push(j.b);
levels[level].i = i + 1;
levels[++level] = {a:item, b:j.b, i:0};
i = -1;
len = item.length;
}
}
else {
levels[level].b.push(item);
}
if(++i == len && level > 0) {
levels.pop();
i = levels[--level].i;
len = levels[level].a.length;
}
}
return encountered[0].b;
}
else {
return this.slice(0);
}
};
The following is an example of how to call this function to do a deep copy of a recursive array:
// Create a recursive array to prove that the cloning function can handle it.
var arrOriginal = [1,2,3];
arrOriginal.push(arrOriginal);
// Make a shallow copy of the recursive array.
var arrShallowCopy = arrOriginal.clone();
// Prove that the shallow copy isn't the same as a deep copy by showing that
// arrShallowCopy contains arrOriginal.
alert("It is " + (arrShallowCopy[3] === arrOriginal)
+ " that arrShallowCopy contains arrOriginal.");
// Make a deep copy of the recursive array.
var arrDeepCopy = arrOriginal.clone(true);
// Prove that the deep copy really works by showing that the original array is
// not the fourth item in arrDeepCopy but that this new array is.
alert("It is "
+ (arrDeepCopy[3] !== arrOriginal && arrDeepCopy === arrDeepCopy[3])
+ " that arrDeepCopy contains itself and not arrOriginal.");
You can play around with this code here at JS Bin.