JavaScript equivalente ao in_array () do PHP


223

Existe uma maneira no JavaScript comparar valores de uma matriz e ver se está em outra matriz?

Semelhante à in_arrayfunção do PHP ?

Respostas:


258

Não, não tem um. Por esse motivo, as bibliotecas mais populares vêm com uma em seus pacotes de utilitários. Confira jQuery inArray e do Prototype Array.indexOf para exemplos.

A implementação do jQuery é tão simples quanto você pode esperar:

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

Se você estiver lidando com uma quantidade sensata de elementos da matriz, o procedimento acima será bem-sucedido.

EDIT : Opa. Eu nem percebi que você queria ver se uma matriz estava dentro de outra. De acordo com a documentação do PHP, este é o comportamento esperado do 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

O código postado por Chris e Alex não segue esse comportamento. Alex é a versão oficial do indexOf do Prototype e Chris é mais parecido com o PHP array_intersect. Isso faz o que você deseja:

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

E este é o meu teste do acima exposto:

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

Observe que eu intencionalmente não estendi o protótipo Array, pois geralmente é uma má idéia fazê-lo.


1
jQuery.inArray()se não retornar boolean. Ele retorna o índice do elemento encontrado ou -1, se não encontrado
Brad Kent

Devido à alta classificação - você deve marcar sua resposta como desatualizada
Gerfried 16/10

1
esta é a documentação de indexOf w3schools.com/jsref/jsref_indexof_array.asp
yussan

74

Existe agora Array.prototype.includes:

O método includes () determina se uma matriz inclui um determinado elemento, retornando verdadeiro ou falso, conforme apropriado.

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

Sintaxe

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

66

Array.indexOffoi introduzido no JavaScript 1.6, mas não é suportado em navegadores mais antigos. Felizmente, os funcionários da Mozilla fizeram todo o trabalho duro por você e forneceram isso para compatibilidade:

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

Existem até alguns trechos de uso úteis para o seu prazer em scripts.


Esta é uma implementação melhor / mais segura / melhor dos links / códigos postados aqui já; as especificações não exigem verificação de matrizes dentro do palheiro, e é isso que o OP deseja.
Paolo Bergantino

3
Aliás, qual é o propósito this.length >>> 0? Isso é uma conversão para um tipo de número?
harto 24/04

3
Array.indexOfagora é padronizado pelo ECMAScript Fifth Edition, portanto deve ser considerado a maneira 'nativa' adequada de fazê-lo. Você ainda precisará farejar e fornecer esse backup para um navegador mais antigo por um longo tempo. @harto: sim, ele se converte this.lengthem um número que pode ser representado como um número inteiro não assinado de 32 bits. Um nativo Arraypode ter apenas um comprimento que já esteja em conformidade com isso, mas a especificação afirma que você pode chamar Array.prototypemétodos em objetos JS nativos que não o são Array. Este e o outro argumento pedante de verificação de coisas é garantir a conformidade absoluta das especificações.
bobince

3
Há uma versão diferente polyfill directamente do Mozilla - developer.mozilla.org/en/docs/Web/JavaScript/Reference/...
Algy Taylor

@harto eu respondo 8 anos após o seu comentário, mas talvez alguém poderia ter a mesma questão => ver stackoverflow.com/questions/1822350/...
Frosty Z

14

Se os índices não estiverem em seqüência ou se não forem consecutivos, o código nas outras soluções listadas aqui será interrompido. Uma solução que funcionaria um pouco melhor pode ser:

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

E, como bônus, aqui está o equivalente ao array_search do PHP (para encontrar a chave do elemento no array:

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

Boa queda em substituição. Realmente facilitou a portabilidade do php para o nó. graças
Rahim Khoja

9

Existe um projeto chamado Locutus , que implementa funções PHP em Javascript e in_array () está incluído, você pode usá-lo exatamente como em PHP.

Exemplos de uso:

in_array('van', myArray);

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

4
Há também uma função inArray nas APIs do JQuery. Verifique api.jquery.com/jQuery.inArray
ahPo

@ahPo, Nice! Mas a implementação do Locutus tem a vantagem de ser puro javascript, sem dependências. Assim, escolher o melhor para suas necessidades
Marcio Mazzucato

1
ou você pode simplesmente importar a função necessária do 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

A solução jQuery está disponível, consulte a documentação aqui: http://api.jquery.com/jquery.inarray/

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

3
não se esqueça de verificar assim: if ($. inArray (10, [8, 9, 10, 11])> -1) porque fiz assim: if ($. inArray (10, [8, 9, 10, 11]))) e sempre retorna true
temirbek

PS: Isso é sensível ao tipo; portanto, se procurar números, verifique se os tipos de dados correspondem! ou seja: $ .inArray ('10', [8, 9, 10, 11]); retornaria -1
Oliver M Grech


3

Se você deseja apenas verificar se um único valor está em uma matriz, o código de Paolo fará o trabalho. Se você deseja verificar quais valores são comuns a ambas as matrizes, convém algo assim (usando a função inArray de 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;
}

Isso retornará uma matriz de valores que estão em ambos ae b. Matematicamente, essa é uma interseção das duas matrizes.

EDIT: Veja o Código Editado de Paolo para a solução do seu problema. :)


Embora isso seja legal, não é realmente o que o OP solicitou; ele não replica a funcionalidade do in_array do PHP.
Paolo Bergantino

3

Se você precisar de todos os parâmetros disponíveis do PHP , use este:

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

Adicione esse código ao seu projeto e use os métodos inArray no estilo de objeto

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)

onde palheiro é uma matriz e agulha é um elemento na matriz. Se o elemento não encontrado for retornado indefinido, o mesmo elemento.


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

Encontrei uma ótima solução jQuery aqui no SO.

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

Eu gostaria que alguém publicasse um exemplo de como fazer isso em sublinhado.


1
function in_array(needle, haystack){

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

Isso retorna apenas se é o primeiro elemento da matriz; se indexOf(needle) > 0retornar falso
DiMono

0

Um equivalente de in_arraycom underscoreé _.indexOf

Exemplos:

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


0

Se você for usá-lo em uma classe e se preferir que seja funcional (e funcione em todos os navegadores):

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

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

    return result;
}

Espero que ajude alguém :-)

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.