29

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);
}
1
  • 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--) Commented Oct 19, 2016 at 20:47

14 Answers 14

30

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]);
}
Sign up to request clarification or add additional context in comments.

2 Comments

A bit of explaining would be nice. Arrays are converted to strings implicitly when used as object keys.
@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.
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]);

1 Comment

As mentioned in the comments here, this doesn't work when searchJson = ['3',566,23,79]
6
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).

Comments

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;
    }
}

2 Comments

Nice, but you're using "return" (needlessly) outside a function which will throw an error.
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
3

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()

Comments

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);

Comments

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;
}

3 Comments

But the OP wants to search an array, not test if two arrays are equal.
He want to search an Array in an Array. So he can use this method for any collection of Array.
I'm saying that a sample usage would be helpful.
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.

Comments

1

Use lodash isEqual

const isValIncludedInAr = ar.some(element => isEqual(element, val)) 

Comments

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

Comments

0

Use this instead

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

Comments

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]]

Comments

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}`);
  }
}

Comments

0

if you have main list and want check second list is contain main list You can use the following method:

    let classList= ['ant-btn', 'css-dev-only-do-not-override-nllxry', 'ant-btn-default', 'ant-btn-icon-only', 'ant-btn-rtl', 'edit', 'ant-tooltip-open']
classList.filter(a=>['changePassword','edit','showPermission'].indexOf(a)>0)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.