I have an array with nested arrays that looks like this:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
When I try and find if the array tw
contains a passed in array, I always get a result of -1.
For example:
var test = $.inArray([3, 0], tw);
var test2 = tw.indexOf([3, 0]);
both return -1, even though the first object in the array is [3,0]
How do I find out if a specific array of arrays is contained in my array?
Oh, and I've only tested it on IE9 so far.
indexOf() The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
Introduction to the JavaScript array indexOf() method To find the position of an element in an array, you use the indexOf() method. This method returns the index of the first occurrence the element that you want to find, or -1 if the element is not found.
You cannot use indexOf to do complicated arrays (unless you serialize it making everything each coordinate into strings), you will need to use a for loop (or while) to search for that coordinate in that array assuming you know the format of the array (in this case it is 2d).
To find the index of an object in an array, by a specific property: Use the map() method to iterate over the array, returning only the value of the relevant property. Call the indexOf() method on the returned from map array. The indexOf method returns the index of the first occurrence of a value in an array.
That's because you're searching for a different object. indexOf()
uses strict equality comparisons (like the ===
operator) and [3, 0] === [3, 0]
returns false.
You'll need to search manually. Here's an example using a more generic indexOf()
function that uses a custom comparer function (with an improvement suggested by @ajax333221 in the comments):
// Shallow array comparer
function arraysIdentical(arr1, arr2) {
var i = arr1.length;
if (i !== arr2.length) {
return false;
}
while (i--) {
if (arr1[i] !== arr2[i]) {
return false;
}
}
return true;
}
function indexOf(arr, val, comparer) {
for (var i = 0, len = arr.length; i < len; ++i) {
if ( i in arr && comparer(arr[i], val) ) {
return i;
}
}
return -1;
}
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
alert( indexOf(tw, [3, 0], arraysIdentical) ); // Alerts 0
Arrays are objects. [3, 0] does not equal [3, 0] as they are different objects. That is why your inArray fails.
Because you're comparing two difference instance of array. Comparing objects returns true
only if they're the same instance, it doesn't matter if they contain the same data.
In your case, you could use this approach:
var tw = [[3, 0], [11, 0], [3, 14], [11, 14]];
if (~tw.join(";").split(";").indexOf(String([3, 0]))) {
// ...
}
Or something more ortodox like:
if (tw.filter(function(v) { return String(v) === String([3, 10]) })[0]) {
// ...
}
Where the condition can be adjusted depends by the content of the arrays.
For infinite nested search:
function indexOfArr(arr1, fnd1) {
var i, len1;
//compare every element on the array
for (i = 0, len1 = arr1.length; i < len1; i++) {
//index missing, leave to prevent false-positives with 'undefined'
if (!(i in arr1)) {
continue;
}
//if they are exactly equal, return the index
if (elementComparer(arr1[i], fnd1)) {
return i;
}
}
//no match found, return false
return -1;
}
function elementComparer(fnd1, fnd2) {
var i, len1, len2, type1, type2, iin1, iin2;
//store the types of fnd1 and fnd2
type1 = typeof fnd1;
type2 = typeof fnd2;
//unwanted results with '(NaN!==NaN)===true' so we exclude them
if (!((type1 == "number" && type2 == "number") && (fnd1 + "" == "NaN" && fnd2 + "" == "NaN"))) {
//unwanted results with '(typeof null==="object")===true' so we exclude them
if (type1 == "object" && fnd1 + "" != "null") {
len1 = fnd1.length;
//unwanted results with '(typeof null==="object")===true' so we exclude them
if (type2 == "object" && fnd2 + "" != "null") {
len2 = fnd2.length;
//if they aren't the same length, return false
if (len1 !== len2) {
return false;
}
//compare every element on the array
for (i = 0; i < len1; i++) {
iin1 = i in fnd1;
iin2 = i in fnd2;
//if either index is missing...
if (!(iin1 && iin2)) {
//they both are missing, leave to prevent false-positives with 'undefined'
if (iin1 == iin2) {
continue;
}
//NOT the same, return false
return false;
}
//if they are NOT the same, return false
if (!elementComparer(fnd1[i], fnd2[i])) {
return false;
}
}
} else {
//NOT the same, return false
return false;
}
} else {
//if they are NOT the same, return false
if (fnd1 !== fnd2) {
return false;
}
}
}
//if it successfully avoided all 'return false', then they are equal
return true;
}
Notes:
jsFiddle demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With