Splice confusion - javascript

I've been going through the rot.js tutorial located here and I'm making sense of the majority of the examples.
However, I'm confused by one line of code and I was hoping someone could explain what's going on.
This is in the Game._generateBoxes function toward the bottom of the page:
var key = freeCells.splice(index, 1)[0];
I understand that it's removing one element from location index from the freeCells array and assigning it to key. I don't understand what the [0] is doing at the end. I tried removing it and it appeared to function normally. What is this accomplishing?

var key = freeCells.splice(index, 1);
… assigns an array with one member to key.
var key = freeCells.splice(index, 1)[0];
… assigns the value of the member of the aforementioned array and then discards the array.
var index = 1;
function one () {
var freeCells = ['a', 'b', 'c']
var key = freeCells.splice(index, 1)[0];
alert(typeof key);
}
function two () {
var freeCells = ['a', 'b', 'c']
var key = freeCells.splice(index, 1);
alert(typeof key);
}
one(); two();

Related

Push to array not working inside If statement, but works one level higher in for loop. Google Script / JavaScript

I am trying to parse through a 2D array, remove empty cells, and then push it to a new 2D array. When I do the .push([]) step before the IF statement, everything works fine but unfortunately that pushes an empty array every iteration of the for loop. When I try to put that line within the If statement, I get the following error: TypeError: Cannot read property 'push' of undefined.
This doesn't work:
var i=0;
var oA = [];
for(i; i<bRows;i++)
{
if(nbaValues[i][0]){
oA.push([]);
for(var j=0;j<bCol;j++){
oA[i].push(nbaValues[i][j]);
}
}
}
Logger.log(oA);
While this works:
var i=0;
var oA = [];
for(i; i<bRows;i++)
{
oA.push([]);
if(nbaValues[i][0]){
for(var j=0;j<bCol;j++){
oA[i].push(nbaValues[i][j]);
}
}
}
Logger.log(oA);
Thanks in advance!
Does this help?
const has_empty = ['a',,'b',,'c' ];
console.log(has_empty); // output ['a', undefined, 'b', undefined, 'c']
const no_empty = has_empty.filter(item => item);
console.log(no_empty); // output ['a', 'b', 'c']

Leaflet angular. can i write a loop inside an array? [duplicate]

How can I add an object to an array (in javascript or jquery)?
For example, what is the problem with this code?
function() {
var a = new array();
var b = new object();
a[0] = b;
}
I would like to use this code to save many objects in the array of function1 and call function2 to use the object in the array.
How can I save an object in an array?
How can I put an object in an array and save it to a variable?
Put anything into an array using Array.push().
var a=[], b={};
a.push(b);
// a[0] === b;
Extra information on Arrays
Add more than one item at a time
var x = ['a'];
x.push('b', 'c');
// x = ['a', 'b', 'c']
Add items to the beginning of an array
var x = ['c', 'd'];
x.unshift('a', 'b');
// x = ['a', 'b', 'c', 'd']
Add the contents of one array to another
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
x.push.apply(x, y);
// x = ['a', 'b', 'c', 'd', 'e', 'f']
// y = ['d', 'e', 'f'] (remains unchanged)
Create a new array from the contents of two arrays
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
var z = x.concat(y);
// x = ['a', 'b', 'c'] (remains unchanged)
// y = ['d', 'e', 'f'] (remains unchanged)
// z = ['a', 'b', 'c', 'd', 'e', 'f']
var years = [];
for (i= 2015;i<=2030;i=i+1){
years.push({operator : i})
}
here array years is having values like
years[0]={operator:2015}
years[1]={operator:2016}
it continues like this.
First of all, there is no object or array. There are Object and Array. Secondly, you can do that:
a = new Array();
b = new Object();
a[0] = b;
Now a will be an array with b as its only element.
Using ES6 notation, you can do something like this:
For appending you can use the spread operator like this:
var arr1 = [1,2,3]
var obj = 4
var newData = [...arr1, obj] // [1,2,3,4]
console.log(newData);
JavaScript is case-sensitive. Calling new array() and new object() will throw a ReferenceError since they don't exist.
It's better to avoid new Array() due to its error-prone behavior.
Instead, assign the new array with = [val1, val2, val_n]. For objects, use = {}.
There are many ways when it comes to extending an array (as shown in John's answer) but the safest way would be just to use concat instead of push. concat returns a new array, leaving the original array untouched. push mutates the calling array which should be avoided, especially if the array is globally defined.
It's also a good practice to freeze the object as well as the new array in order to avoid unintended mutations. A frozen object is neither mutable nor extensible (shallowly).
Applying those points and to answer your two questions, you could define a function like this:
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
Usage:
// Given
const myArray = ["A", "B"];
// "save it to a variable"
const newArray = appendObjTo(myArray, {hello: "world!"});
// returns: ["A", "B", {hello: "world!"}]. myArray did not change.
/* array literal */
var aData = [];
/* object constructur */
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.fullname = function() {
// return (this.firstname + " " + this.lastname);
return (`${this.firstname} ${this.lastname}`); // es6 template string
};
}
/* store object into array */
aData[aData.length] = new Person("Java", "Script"); // aData[0]
aData.push(new Person("John", "Doe"));
aData.push(new Person("Anna", "Smith"));
aData.push(new Person("Black", "Pearl"));
aData[aData.length] = new Person("stack", "overflow"); // aData[4]
/* loop array */
for (var i in aData) {
alert(aData[i].fullname());
}
/* convert array of object into string json */
var jsonString = JSON.stringify(aData);
document.write(jsonString);
Push object into array
With push you can even add multiple objects to an array
let myArray = [];
myArray.push(
{name:"James", dataType:TYPES.VarChar, Value: body.Name},
{name:"Boo", dataType:TYPES.VarChar, Value: body.Name},
{name:"Alina", dataType:TYPES.VarChar, Value: body.Name}
);
Expanding Gabi Purcaru's answer to include an answer to number 2.
a = new Array();
b = new Object();
a[0] = b;
var c = a[0]; // c is now the object we inserted into a...
obejct is clearly a typo. But both object and array need capital letters.
You can use short hands for new Array and new Object these are [] and {}
You can push data into the array using .push. This adds it to the end of the array. or you can set an index to contain the data.
function saveToArray() {
var o = {};
o.foo = 42;
var arr = [];
arr.push(o);
return arr;
}
function other() {
var arr = saveToArray();
alert(arr[0]);
}
other();
You can use with Spread Operator (...) like this:
let arr = [{num: 1, char: "a"}, {num: 2, char: "b"}];
arr = [...arr,{num: 3, char: "c"}];
//...arr --> spread operator
console.log(arr);
On alternativ answer is this.
if you have and array like this: var contacts = [bob, mary];
and you want to put another array in this array, you can do that in this way:
Declare the function constructor
function add (firstName,lastName,email,phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneNumber = phoneNumber;
}
make the object from the function:
var add1 = new add("Alba","Fas","Des#gmail.com","[098] 654365364");
and add the object in to the array:
contacts[contacts.length] = add1;
a=[];
a.push(['b','c','d','e','f']);
The way I made object creator with auto list:
var list = [];
function saveToArray(x) {
list.push(x);
};
function newObject () {
saveToArray(this);
};
Performance
Today 2020.12.04 I perform tests on MacOs HighSierra 10.13.6 on Chrome v86, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
For all browsers
in-place solution based on length (B) is fastest for small arrays, and in Firefox for big too and for Chrome and Safari is fast
in-place solution based on push (A) is fastest for big arrays on Chrome and Safari, and fast for Firefox and small arrays
in-place solution C is slow for big arrays and medium fast for small
non-in-place solutions D and E are slow for big arrays
non-in-place solutions E,F and D(on Firefox) are slow for small arrays
Details
I perform 2 tests cases:
for small array with 10 elements - you can run it HERE
for big array with 1M elements - you can run it HERE
Below snippet presents differences between solutions
A,
B,
C,
D,
E,
F
PS: Answer B was deleted - but actually it was the first answer which use this technique so if you have access to see it please click on "undelete".
// https://stackoverflow.com/a/6254088/860099
function A(a,o) {
a.push(o);
return a;
}
// https://stackoverflow.com/a/47506893/860099
function B(a,o) {
a[a.length] = o;
return a;
}
// https://stackoverflow.com/a/6254088/860099
function C(a,o) {
return a.concat(o);
}
// https://stackoverflow.com/a/50933891/860099
function D(a,o) {
return [...a,o];
}
// https://stackoverflow.com/a/42428064/860099
function E(a,o) {
const frozenObj = Object.freeze(o);
return Object.freeze(a.concat(frozenObj));
}
// https://stackoverflow.com/a/6254088/860099
function F(a,o) {
a.unshift(o);
return a;
}
// -------
// TEST
// -------
[A,B,C,D,E,F].map(f=> {
console.log(`${f.name} ${JSON.stringify(f([1,2],{}))}`)
})
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
You are running into a scope problem if you use your code as such. You have to declare it outside the functions if you plan to use it between them (or if calling, pass it as a parameter).
var a = new Array();
var b = new Object();
function first() {
a.push(b);
// Alternatively, a[a.length] = b
// both methods work fine
}
function second() {
var c = a[0];
}
// code
first();
// more code
second();
// even more code

how to prevent adding duplicate keys to a javascript array

I found a lot of related questions with answers talking about for...in loops and using hasOwnProperty but nothing I do works properly. All I want to do is check whether or not a key exists in an array and if not, add it.
I start with an empty array then add keys as the page is scrubbed with jQuery.
Initially, I hoped that something simple like the following would work: (using generic names)
if (!array[key])
array[key] = value;
No go. Followed it up with:
for (var in array) {
if (!array.hasOwnProperty(var))
array[key] = value;
}
Also tried:
if (array.hasOwnProperty(key) == false)
array[key] = value;
None of this has worked. Either nothing is pushed to the array or what I try is no better than simply declaring array[key] = value Why is something so simple so difficult to do. Any ideas to make this work?
Generally speaking, this is better accomplished with an object instead since JavaScript doesn't really have associative arrays:
var foo = { bar: 0 };
Then use in to check for a key:
if ( !( 'bar' in foo ) ) {
foo['bar'] = 42;
}
As was rightly pointed out in the comments below, this method is useful only when your keys will be strings, or items that can be represented as strings (such as numbers).
var a = [1,2,3], b = [4,1,5,2];
b.forEach(function(value){
if (a.indexOf(value)==-1) a.push(value);
});
console.log(a);
// [1, 2, 3, 4, 5]
For more details read up on Array.indexOf.
If you want to rely on jQuery, instead use jQuery.inArray:
$.each(b,function(value){
if ($.inArray(value,a)==-1) a.push(value);
});
If all your values are simply and uniquely representable as strings, however, you should use an Object instead of an Array, for a potentially massive speed increase (as described in the answer by #JonathanSampson).
A better alternative is provided in ES6 using Sets. So, instead of declaring Arrays, it is recommended to use Sets if you need to have an array that shouldn't add duplicates.
var array = new Set();
array.add(1);
array.add(2);
array.add(3);
console.log(array);
// Prints: Set(3) {1, 2, 3}
array.add(2); // does not add any new element
console.log(array);
// Still Prints: Set(3) {1, 2, 3}
If you're already using spread...
let colors = ['red', 'orange', 'yellow'];
let moreColors = ['orange', 'green'];
let mergedColors = [...colors, ...moreColors];
and want to avoid duplicates...
let mergedColors = [...colors, ...moreColors.filter(c => !colors.includes(c)) ];
You can try this:
var names = ["Mike","Matt","Nancy","Adam","Jenny","Nancy","Carl"];
var uniqueNames = [];
$.each(names, function(i, el){
if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el);
});
Easiest way to find duplicate values in a JavaScript array
The logic is wrong. Consider this:
x = ["a","b","c"]
x[0] // "a"
x["0"] // "a"
0 in x // true
"0" in x // true
x.hasOwnProperty(0) // true
x.hasOwnProperty("0") // true
There is no reason to loop to check for key (or indices for arrays) existence. Now, values are a different story...
Happy coding
function check (list){
var foundRepeatingValue = false;
var newList = [];
for(i=0;i<list.length;i++){
var thisValue = list[i];
if(i>0){
if(newList.indexOf(thisValue)>-1){
foundRepeatingValue = true;
console.log("getting repeated");
return true;
}
} newList.push(thisValue);
} return false;
}
var list1 = ["dse","dfg","dse"];
check(list1);
Output:
getting repeated
true
let x = "farceus";
let y = "character";
const commonCharacters = function (string1, string2) {
let duplicateCharacter = "";
for (let i = 0; i < string1.length; i += 1) {
if (duplicateCharacter.indexOf(string1[i]) === -1) {
if (string2.indexOf(string1[i]) !== -1) {
duplicateCharacter += string1[i];
}
}
}
return [...duplicateCharacter];
};
console.log(commonCharacters(x, y));

How to add an object to an array

How can I add an object to an array (in javascript or jquery)?
For example, what is the problem with this code?
function() {
var a = new array();
var b = new object();
a[0] = b;
}
I would like to use this code to save many objects in the array of function1 and call function2 to use the object in the array.
How can I save an object in an array?
How can I put an object in an array and save it to a variable?
Put anything into an array using Array.push().
var a=[], b={};
a.push(b);
// a[0] === b;
Extra information on Arrays
Add more than one item at a time
var x = ['a'];
x.push('b', 'c');
// x = ['a', 'b', 'c']
Add items to the beginning of an array
var x = ['c', 'd'];
x.unshift('a', 'b');
// x = ['a', 'b', 'c', 'd']
Add the contents of one array to another
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
x.push.apply(x, y);
// x = ['a', 'b', 'c', 'd', 'e', 'f']
// y = ['d', 'e', 'f'] (remains unchanged)
Create a new array from the contents of two arrays
var x = ['a', 'b', 'c'];
var y = ['d', 'e', 'f'];
var z = x.concat(y);
// x = ['a', 'b', 'c'] (remains unchanged)
// y = ['d', 'e', 'f'] (remains unchanged)
// z = ['a', 'b', 'c', 'd', 'e', 'f']
var years = [];
for (i= 2015;i<=2030;i=i+1){
years.push({operator : i})
}
here array years is having values like
years[0]={operator:2015}
years[1]={operator:2016}
it continues like this.
First of all, there is no object or array. There are Object and Array. Secondly, you can do that:
a = new Array();
b = new Object();
a[0] = b;
Now a will be an array with b as its only element.
Using ES6 notation, you can do something like this:
For appending you can use the spread operator like this:
var arr1 = [1,2,3]
var obj = 4
var newData = [...arr1, obj] // [1,2,3,4]
console.log(newData);
JavaScript is case-sensitive. Calling new array() and new object() will throw a ReferenceError since they don't exist.
It's better to avoid new Array() due to its error-prone behavior.
Instead, assign the new array with = [val1, val2, val_n]. For objects, use = {}.
There are many ways when it comes to extending an array (as shown in John's answer) but the safest way would be just to use concat instead of push. concat returns a new array, leaving the original array untouched. push mutates the calling array which should be avoided, especially if the array is globally defined.
It's also a good practice to freeze the object as well as the new array in order to avoid unintended mutations. A frozen object is neither mutable nor extensible (shallowly).
Applying those points and to answer your two questions, you could define a function like this:
function appendObjTo(thatArray, newObj) {
const frozenObj = Object.freeze(newObj);
return Object.freeze(thatArray.concat(frozenObj));
}
Usage:
// Given
const myArray = ["A", "B"];
// "save it to a variable"
const newArray = appendObjTo(myArray, {hello: "world!"});
// returns: ["A", "B", {hello: "world!"}]. myArray did not change.
/* array literal */
var aData = [];
/* object constructur */
function Person(firstname, lastname) {
this.firstname = firstname;
this.lastname = lastname;
this.fullname = function() {
// return (this.firstname + " " + this.lastname);
return (`${this.firstname} ${this.lastname}`); // es6 template string
};
}
/* store object into array */
aData[aData.length] = new Person("Java", "Script"); // aData[0]
aData.push(new Person("John", "Doe"));
aData.push(new Person("Anna", "Smith"));
aData.push(new Person("Black", "Pearl"));
aData[aData.length] = new Person("stack", "overflow"); // aData[4]
/* loop array */
for (var i in aData) {
alert(aData[i].fullname());
}
/* convert array of object into string json */
var jsonString = JSON.stringify(aData);
document.write(jsonString);
Push object into array
With push you can even add multiple objects to an array
let myArray = [];
myArray.push(
{name:"James", dataType:TYPES.VarChar, Value: body.Name},
{name:"Boo", dataType:TYPES.VarChar, Value: body.Name},
{name:"Alina", dataType:TYPES.VarChar, Value: body.Name}
);
Expanding Gabi Purcaru's answer to include an answer to number 2.
a = new Array();
b = new Object();
a[0] = b;
var c = a[0]; // c is now the object we inserted into a...
obejct is clearly a typo. But both object and array need capital letters.
You can use short hands for new Array and new Object these are [] and {}
You can push data into the array using .push. This adds it to the end of the array. or you can set an index to contain the data.
function saveToArray() {
var o = {};
o.foo = 42;
var arr = [];
arr.push(o);
return arr;
}
function other() {
var arr = saveToArray();
alert(arr[0]);
}
other();
You can use with Spread Operator (...) like this:
let arr = [{num: 1, char: "a"}, {num: 2, char: "b"}];
arr = [...arr,{num: 3, char: "c"}];
//...arr --> spread operator
console.log(arr);
On alternativ answer is this.
if you have and array like this: var contacts = [bob, mary];
and you want to put another array in this array, you can do that in this way:
Declare the function constructor
function add (firstName,lastName,email,phoneNumber) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.phoneNumber = phoneNumber;
}
make the object from the function:
var add1 = new add("Alba","Fas","Des#gmail.com","[098] 654365364");
and add the object in to the array:
contacts[contacts.length] = add1;
a=[];
a.push(['b','c','d','e','f']);
The way I made object creator with auto list:
var list = [];
function saveToArray(x) {
list.push(x);
};
function newObject () {
saveToArray(this);
};
Performance
Today 2020.12.04 I perform tests on MacOs HighSierra 10.13.6 on Chrome v86, Safari v13.1.2 and Firefox v83 for chosen solutions.
Results
For all browsers
in-place solution based on length (B) is fastest for small arrays, and in Firefox for big too and for Chrome and Safari is fast
in-place solution based on push (A) is fastest for big arrays on Chrome and Safari, and fast for Firefox and small arrays
in-place solution C is slow for big arrays and medium fast for small
non-in-place solutions D and E are slow for big arrays
non-in-place solutions E,F and D(on Firefox) are slow for small arrays
Details
I perform 2 tests cases:
for small array with 10 elements - you can run it HERE
for big array with 1M elements - you can run it HERE
Below snippet presents differences between solutions
A,
B,
C,
D,
E,
F
PS: Answer B was deleted - but actually it was the first answer which use this technique so if you have access to see it please click on "undelete".
// https://stackoverflow.com/a/6254088/860099
function A(a,o) {
a.push(o);
return a;
}
// https://stackoverflow.com/a/47506893/860099
function B(a,o) {
a[a.length] = o;
return a;
}
// https://stackoverflow.com/a/6254088/860099
function C(a,o) {
return a.concat(o);
}
// https://stackoverflow.com/a/50933891/860099
function D(a,o) {
return [...a,o];
}
// https://stackoverflow.com/a/42428064/860099
function E(a,o) {
const frozenObj = Object.freeze(o);
return Object.freeze(a.concat(frozenObj));
}
// https://stackoverflow.com/a/6254088/860099
function F(a,o) {
a.unshift(o);
return a;
}
// -------
// TEST
// -------
[A,B,C,D,E,F].map(f=> {
console.log(`${f.name} ${JSON.stringify(f([1,2],{}))}`)
})
<script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.20/lodash.min.js" integrity="sha512-90vH1Z83AJY9DmlWa8WkjkV79yfS2n2Oxhsi2dZbIv0nC4E6m5AbH8Nh156kkM7JePmqD6tcZsfad1ueoaovww==" crossorigin="anonymous"> </script>
This shippet only presents functions used in performance tests - it not perform tests itself!
And here are example results for chrome
You are running into a scope problem if you use your code as such. You have to declare it outside the functions if you plan to use it between them (or if calling, pass it as a parameter).
var a = new Array();
var b = new Object();
function first() {
a.push(b);
// Alternatively, a[a.length] = b
// both methods work fine
}
function second() {
var c = a[0];
}
// code
first();
// more code
second();
// even more code

(Deep) copying an array using jQuery [duplicate]

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.

Categories

Resources