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


223

Чи існує спосіб у JavaScript порівняти значення з одного масиву та побачити, чи є він в іншому масиві?

Схожа на in_arrayфункцію PHP ?

Відповіді:


258

Ні, його немає. З цієї причини найпопулярніші бібліотеки поставляються з такою у своїх утилітах. Перевірте JQuery в inArray і прототипу 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

Код, опублікований Крісом та Алексом, не відповідає цій поведінці. Алекс є офіційною версією прототипу 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

Зауважте, що я навмисно не поширював прототип масиву, оскільки це, як правило, погана ідея.


1
jQuery.inArray()нічого НЕ повертають логічне значення. Він повертає індекс знайденого елемента або -1, якщо його не знайдено
Бред Кент

Через високий рейтинг - ви повинні позначити свою відповідь застарілою
Герфрід

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? Це перетворення на тип числа?
harto

3
Array.indexOfтепер стандартизована п'ятим виданням ECMAScript, тому слід вважати правильним "рідним" способом цього робити. Однак вам все одно доведеться нюхати та надавати цю резервну копію для старих веб-переглядачів. @harto: так, воно перетворюється this.lengthна число, яке може бути представлено у вигляді 32-бітного цілого числа без підпису. Уроджений Arrayможе мати лише довжину, яка вже відповідає цьому, але специфікація стверджує, що ви можете викликати Array.prototypeметоди на нативних JS-об'єктах, які це не так Array. Цей та інший педантичний аргумент, що перевіряє матеріал, повинен гарантувати абсолютну відповідність специфіці.
bobince

3
Існує інша версія поліфункції, доступна безпосередньо від 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's 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

@ahPo, приємно! Але реалізація Locutus має перевагу - чистий javascript без залежностей. Отож, виберіть найкращу для ваших потреб
Marcio Mazzucato

1
або ви можете просто імпортувати потрібну функцію з Locutus.
Niket Pathak


5
var a = [1,2,3,4,5,6,7,8,9];

var isSixInArray = a.filter(function(item){return item==6}).length ? true : false;

var isSixInArray = a.indexOf(6)>=0;

5

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

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

3
не забудьте перевірити так: якщо ($. inArray (10, [8, 9, 10, 11])> -1), тому що я зробив це так: if ($. inArray (10, [8, 9, 10, 11])) і це завжди повертається правдою
temirbek

PS: Це чутливий тип, тому, якщо перевіряєте цифри, переконайтеся, що ваші типи даних збігаються! тобто: $ .inArray ('10', [8, 9, 10, 11]); повернеться -1
Олівер М Греч


3

Якщо ви хочете лише перевірити, чи є одне значення в масиві, тоді код Паоло виконає цю роботу. Якщо ви хочете перевірити, які значення є спільними для обох масивів, вам потрібно щось подібне (використовуючи функцію 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");



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він повернеться неправдивим
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.