28

Let's say we have the following js array

var ar = [
   [2,6,89,45],
   [3,566,23,79],
   [434,677,9,23]
];

var val = [3,566,23,79];

Is there a js builtin function or jQuery one with which you can search the array ar for val?

Thanks

***UPDATE*************

Taking fusion's response I created this prototype

Array.prototype.containsArray = function(val) {
    var hash = {};
    for(var i=0; i<this.length; i++) {
        hash[this[i]] = i;
    }
    return hash.hasOwnProperty(val);
}
Thomas
  • 4,641
  • 13
  • 44
  • 67
  • 1
    Just want to add a minor comment that moving `this.length` outside the loop would make it much more efficient. Like this, for example: `for (var i = this.length > 0 ? (this.length - 1) : 0; i; i--)` – Andrey Kiselev Oct 19 '16 at 20:47

13 Answers13

28

you could create a hash.

var ar = [
    [2,6,89,45],
    [3,566,23,79],
    [434,677,9,23]
];

var hash = {};
for(var i = 0 ; i < ar.length; i += 1) {
    hash[ar[i]] = i;
}

var val = [434,677,9,23];

if(hash.hasOwnProperty(val)) {
    document.write(hash[val]);
}
fusion
  • 1,257
  • 10
  • 15
  • 8
    A bit of explaining would be nice. Arrays are converted to strings implicitly when used as object keys. – fusion Jun 11 '11 at 10:23
  • @stereofrog I see your point. Example data did not include nested arrays or string values. My answer is a quick way of dealing with the specific task and not a generic method for checking the equality of arrays. – fusion Jun 11 '11 at 10:33
8

You can also use a trick with JSON serializing. It is short and simple, but kind of hacky.
It works, because "[0,1]" === "[0,1]".

Here is the working demo snippet:

Array.prototype.indexOfForArrays = function(search)
{
  var searchJson = JSON.stringify(search); // "[3,566,23,79]"
  var arrJson = this.map(JSON.stringify); // ["[2,6,89,45]", "[3,566,23,79]", "[434,677,9,23]"]

  return arrJson.indexOf(searchJson);
};

var arr = [
   [2,6,89,45],
   [3,566,23,79],
   [434,677,9,23]
];

document.body.innerText = arr.indexOfForArrays([3,566,23,79]);
Yeldar Kurmangaliyev
  • 33,467
  • 12
  • 59
  • 101
  • As mentioned in the [comments here](https://stackoverflow.com/a/68747829/6908282), this doesn't work when `searchJson = ['3',566,23,79]` – Gangula Nov 17 '22 at 08:11
5
function indexOfArray(val, array) {
  var hash = {};
  for (var i = 0; i < array.length; i++) {
    hash[array[i]] = i;
  }
  return (hash.hasOwnProperty(val)) ? hash[val] : -1;
};

I consider this more useful for than containsArray(). It solves the same problem (using a hash table) but returns the index (rather than only boolean true/false).

ashleedawg
  • 20,365
  • 9
  • 72
  • 105
Hans
  • 51
  • 1
  • 1
3

You can use Array.prototype.some(), Array.prototype.every() to check each element of each array.

var ar = [
  [2, 6, 89, 45],
  [3, 566, 23, 79],
  [434, 677, 9, 23]
];

var val = [3, 566, 23, 79];

var bool = ar.some(function(arr) {
  return arr.every(function(prop, index) {
    return val[index] === prop
  })
});

console.log(bool);
guest271314
  • 1
  • 15
  • 104
  • 177
3

Can you try this?

var ar = [
   [2,6,89,45],
   [3,566,23,79],
   [434,677,9,23]
];

var val = [3,566,23,79];


var sval = val.join("");
for(var i in ar)
{
    var sar = ar[i].join("");
    if (sar==sval) 
    {
        alert("found!");
        break;
    }
}
sudipto
  • 2,472
  • 1
  • 17
  • 21
  • Nice, but you're using "return" (needlessly) outside a function which will throw an error. – squidbe Jun 11 '11 at 09:56
  • oops! my bad! i actually wrote a function wrapping this code! modifying. though return has nothing to do with this. you can use break; in a loop – sudipto Jun 11 '11 at 09:58
2

Why don't you use javascript array functions?

function filterArrayByValues(array, values) {
            return array.filter(function (arrayItem) {
                return values.some(function (value) {
                    return value === arrayItem;
                });
            });
        }

Or if your array is more complicated, and you want compare only one property but as result return whole object:

  function filterArrayByValues(array, values, propertyName) {
            return array.filter(function (arrayItem) {
                return values.some(function (value) {
                    return value === arrayItem[propertyName];
                });
            });
        }

More about used functions: filter() and some()

Michał Jarzyna
  • 1,836
  • 18
  • 26
1

I guess there is no such JS functionality available. but you can create one

function arrEquals( one, two )
{
    if( one.length != two.length )
    {
        return false;
    }
    for( i = 0; i < one.length; i++ )
    {
        if( one[i] != two[i] )
        {
            return false;
        }
    }
    return true;
}
Talha Ahmed Khan
  • 15,043
  • 10
  • 42
  • 49
1

The problem with this is that of object/array equality in Javascript. Essentially, the problem is that two arrays are not equal, even if they have the same values. You need to loop through the array and compare the members to your search key (val), but you'll need a way of accurately comparing arrays.

The easiest way round this is to use a library that allows array/object comparison. underscore.js has a very attractive method to do this:

for (var i = 0; i < ar.length; i++) {
    if (_.isEqual(ar[i], val)) {
        // value is present
    }
}

If you don't want to use another library (though I would urge you to -- or at least borrow the message from the Underscore source), you could do this with JSON.stringify...

var valJSON = JSON.stringify(val);
for (var i = 0; i < ar.length; i++) {
    if (valJSON === JSON.stringify(ar[i]) {
        // value is present
    }
}

This will almost certainly be significantly slower, however.

lonesomeday
  • 233,373
  • 50
  • 316
  • 318
0

You can use toString convertion to compare elements

var ar = [
   [2,6,89,45],
   [3,566,23,79],
   [434,677,9,23]
];

var val = [3,566,23,79];

s = !ar.every(a => (a.toString() != val.toString()));
console.log(s) // true
farynaa
  • 330
  • 3
  • 7
0

Use this instead

if (ar.join(".").indexOf(val) > -1) {
 return true;
} else {
 return false;
}
0

Use lodash isEqual

const isValIncludedInAr = ar.some(element => isEqual(element, val)) 
Oz Ben-David
  • 1,589
  • 1
  • 16
  • 26
0

const arrayOne = [2,6,89,45]; 
const arrayTwo = [3,566,23,79];
const arrayThree = [434,677,9,23];

const data = new Set([arrayOne, arrayTwo, arrayThree]);

// Check array if exist
console.log( data.has(arrayTwo) ); // It will return true.

// If you want to make a set into array it's simple
const arrayData = [...data];
console.log(arrayData); // It will return [[2,6,89,45], [3,566,23,79], [434,677,9,23]]
Rajan Karmaker
  • 118
  • 1
  • 7
0

You can simply perform string comparison for primitive values (inside the array):

var ar = [
  [2, 6, 89, 45],
  [3, 566, 23, 79],
  [434, 677, 9, 23],
];

var val = [3, 566, 23, 79];

for (const item of ar) {
  if (item.toString() == val.toString()) {
    console.log(`item found at index: ${ar.indexOf(item)}`);
  }
}

For non-primitive values (like [3, 566, 23, {foo: 'foo'}]), you could check it with JSON.stringify():

if (JSON.stringify(item) == JSON.stringify(val)) {

Whereas, preceding string comparison can produce wrong result.


Alternatively, you can use entries:

for (const [index, value] of ar.entries()) {
  if (value.toString() == val.toString()) {
    console.log(`item found at index: ${index}`);
  }
}
Bhojendra Rauniyar
  • 83,432
  • 35
  • 168
  • 231