JavaScript-эквивалент PHP in_array ()


223

Есть ли способ в JavaScript для сравнения значений из одного массива и посмотреть, находится ли он в другом массиве?

Похоже на in_arrayфункцию PHP ?

Ответы:


258

Нет, его нет. По этой причине большинство популярных библиотек поставляются с одной в своих пакетах утилит. Посмотрите jQuery inArray и Prototype Array.indexOf для примеров.

Реализация этого в jQuery настолько проста, насколько вы можете ожидать:

function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

Если вы имеете дело с нормальным количеством элементов массива, вышеприведенное хорошо сработает.

РЕДАКТИРОВАТЬ : Упс. Я даже не заметил, что вы хотели увидеть, был ли массив внутри другого. Согласно документации PHP, это ожидаемое поведение PHP in_array:

$a = array(array('p', 'h'), array('p', 'r'), 'o');

if (in_array(array('p', 'h'), $a)) {
    echo "'ph' was found\n";
}

if (in_array(array('f', 'i'), $a)) {
    echo "'fi' was found\n";
}

if (in_array('o', $a)) {
    echo "'o' was found\n";
}

// Output:
//  'ph' was found
//  'o' was found

Код, размещенный Крисом и Алексом, не соответствует этому поведению. Алекс - это официальная версия Prototype indexOf, а Крис больше похож на PHP array_intersect. Это делает то, что вы хотите:

function arrayCompare(a1, a2) {
    if (a1.length != a2.length) return false;
    var length = a2.length;
    for (var i = 0; i < length; i++) {
        if (a1[i] !== a2[i]) return false;
    }
    return true;
}

function inArray(needle, haystack) {
    var length = haystack.length;
    for(var i = 0; i < length; i++) {
        if(typeof haystack[i] == 'object') {
            if(arrayCompare(haystack[i], needle)) return true;
        } else {
            if(haystack[i] == needle) return true;
        }
    }
    return false;
}

И это мой тест выше на нем:

var a = [['p','h'],['p','r'],'o'];
if(inArray(['p','h'], a)) {
    alert('ph was found');
}
if(inArray(['f','i'], a)) {
    alert('fi was found');
}
if(inArray('o', a)) {
    alert('o was found');
}  
// Results:
//   alerts 'ph' was found
//   alerts 'o' was found

Обратите внимание, что я намеренно не расширил прототип Array, так как это обычно плохая идея.


1
jQuery.inArray()ничего не возвращают логическое значение. Возвращает индекс найденного элемента или -1, если не найден
Брэд Кент

Из-за высокого рейтинга - вы должны пометить свой ответ как устаревший
Gerfried

1
это документация сайта indexOf w3schools.com/jsref/jsref_indexof_array.asp
yussan

74

Есть сейчас Array.prototype.includes:

Метод include () определяет, включает ли массив определенный элемент, возвращая в зависимости от ситуации true или false.

var a = [1, 2, 3];
a.includes(2); // true 
a.includes(4); // false

Синтаксис

arr.includes(searchElement)
arr.includes(searchElement, fromIndex)

66

Array.indexOfбыл введен в JavaScript 1.6, но он не поддерживается в старых браузерах. К счастью, ребята из Mozilla сделали всю тяжелую работу за вас и предоставили вам это для совместимости:

if (!Array.prototype.indexOf)
{
  Array.prototype.indexOf = function(elt /*, from*/)
  {
    var len = this.length >>> 0;

    var from = Number(arguments[1]) || 0;
    from = (from < 0)
         ? Math.ceil(from)
         : Math.floor(from);
    if (from < 0)
      from += len;

    for (; from < len; from++)
    {
      if (from in this &&
          this[from] === elt)
        return from;
    }
    return -1;
  };
}

Есть даже несколько удобных фрагментов использования для вашего удовольствия от написания сценариев.


Это более приятная / безопасная / лучшая реализация ссылок / кода, размещенных здесь уже; спецификации не требуют проверки массивов внутри стога сена, и это то, что хочет ОП.
Паоло Бергантино

3
Кстати, для чего это нужно this.length >>> 0? Это преобразование в тип Number?
Harto

3
Array.indexOfв настоящее время стандартизирован ECMAScript Fifth Edition, поэтому его следует рассматривать как «родной» способ сделать это. Тем не менее, вам все равно нужно будет прослушивать и предоставлять эту резервную копию для старого браузера в течение длительного времени. @harto: да, он преобразуется this.lengthв число, которое может быть представлено как 32-разрядное целое число без знака. Нативная Arrayможет иметь только длину, которая уже соответствует этому, но спецификация утверждает, что вы можете вызывать Array.prototypeметоды для объектов нативной JS, которые не являются Array. Этот и другие педантичные средства проверки аргументов должны гарантировать абсолютное соответствие спецификациям.
бобинце

3
Существует другая версия polyfill, доступная непосредственно из Mozilla - developer.mozilla.org/en/docs/Web/JavaScript/Reference/…
Алджи Тейлор,

@harto Я отвечаю через 8 лет после вашего комментария, но, возможно, у кого-то еще может возникнуть такой же вопрос => см. stackoverflow.com/questions/1822350/…
Frosty Z

14

Если индексы не в последовательности или индексы не являются последовательными, код в других решениях, перечисленных здесь, сломается. Решение, которое будет работать несколько лучше, может быть:

function in_array(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return true;
    }
    return false;
}

И, в качестве бонуса, вот эквивалент PHP array_search (для нахождения ключа элемента в массиве:

function array_search(needle, haystack) {
    for(var i in haystack) {
        if(haystack[i] == needle) return i;
    }
    return false;
}

Хорошая капля в замене. Действительно упрощено портирование с php на узел. спасибо
Рахим Ходжа

9

Есть проект под названием Locutus , он реализует функции PHP в Javascript, и в него включена in_array () , вы можете использовать его точно так же, как вы используете в PHP.

Примеры использования:

in_array('van', myArray);

in_array(1, otherArray, true); // Forcing strict type

4
В API JQuery также есть функция inArray. Проверьте api.jquery.com/jQuery.inArray
ахПо

@ahPo, Отлично! Но реализация Locutus имеет то преимущество, что является чистым javascript без каких-либо зависимостей. Итак, выберите лучший для ваших нужд
Марсио Маццукато,

1
или вы можете просто импортировать необходимую функцию из Locutus.
Никет Патхак,



5

Доступно решение jQuery, проверьте документацию здесь: http://api.jquery.com/jquery.inarray/

$.inArray( 10, [ 8, 9, 10, 11 ] );

3
не забудьте проверить вот так: if ($. inArray (10, [8, 9, 10, 11])> -1), потому что я сделал это так: if ($. inArray (10, [8, 9, 10, 11])) и всегда возвращается истина
темирбек

PS: Это чувствительно к типу, поэтому при проверке чисел убедитесь, что ваши типы данных совпадают! то есть: $ .inArray ('10', [8, 9, 10, 11]); вернется -1
Оливер М Греч


3

Если вы хотите проверить, есть ли одно значение в массиве, то код Paolo выполнит эту работу. Если вы хотите проверить, какие значения являются общими для обоих массивов, то вам нужно что-то вроде этого (используя функцию inArray от Paolo):

function arrayIntersect(a, b) {
    var intersection = [];

    for(var i = 0; i < a.length; i++) {
        if(inArray(b, a[i]))
            intersection.push(a[i]);
    }

    return intersection;
}

Это вернет массив значений, которые находятся в обоих aи b. (Математически это пересечение двух массивов.)

РЕДАКТИРОВАТЬ: См . Отредактированный код Паоло для решения вашей проблемы. :)


Хотя это хорошо, это не совсем то, о чем просил ФП; он не копирует функциональность PHP in_array.
Паоло Бергантино

3

Если вам нужны все доступные параметры PHP , используйте это:

function in_array(needle, haystack, argStrict) {
    var key = '', strict = !!argStrict;
    if (strict) {
        for (key in haystack) {
            if (haystack[key] === needle) {
                return true;
            }
        }
    }
    else {
        for (key in haystack) {
            if (haystack[key] == needle) {
                return true;
            }
        }
    }
    return false;
}

3

Добавьте этот код в свой проект и используйте методы inArray в стиле объекта

if (!Array.prototype.inArray) {
    Array.prototype.inArray = function(element) {
        return this.indexOf(element) > -1;
    };
} 
//How it work
var array = ["one", "two", "three"];
//Return true
array.inArray("one");


2
haystack.find(value => value == needle)

где стог сена - это массив, а игла - элемент в массиве. Если элемент не найден, будет возвращено неопределенное, иначе тот же элемент.


1
function in_array(what, where) {
    var a=false;
    for (var i=0; i<where.length; i++) {
        if(what == where[i]) {
            a=true;
            break;
        }
    }
    return a;
}

1

Я нашел отличное решение jQuery здесь, на SO.

var success = $.grep(array_a, function(v,i) {
    return $.inArray(v, array_b) !== -1;
}).length === array_a.length;

Я бы хотел, чтобы кто-нибудь опубликовал пример того, как это сделать, в подчеркивании.


1
function in_array(needle, haystack){

    return haystack.indexOf(needle) !== -1;
}

Это только возвращает, является ли это первым элементом в массиве; если indexOf(needle) > 0он вернет false
DiMono

0

Эквивалент in_arrayс underscoreявляется _.indexOf

Примеры:

_.indexOf([3, 5, 8], 8); // returns 2, the index of 8 _.indexOf([3, 5, 8], 10); // returns -1, not found


0

Если вы собираетесь использовать его в классе и предпочитаете, чтобы он был функциональным (и работал во всех браузерах):

inArray: function(needle, haystack)
{
    var result = false;

    for (var i in haystack) {
        if (haystack[i] === needle) {
            result = true;
            break;
        }
    }

    return result;
}

Надеюсь, это кому-нибудь поможет :-)

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.