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 ?

roflwaffle
fonte

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.

Paolo Bergantino
fonte
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)
alemjerus
fonte
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.

Alex Barrett
fonte
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;
}
random_user_name
fonte
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
Marcio Mazzucato
fonte
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
7

Você pode simplesmente usar a função "includes", conforme explicado nesta lição no w3schools

parece

let myArray = ['Kevin', 'Bob', 'Stuart'];
if( myArray.includes('Kevin'))
console.log('Kevin is here');

AbdulRhman Khallil
fonte
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;
Rax Wunter
fonte
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 ] );
Webars
fonte
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. :)

Chris Doble
fonte
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;
}
Andres SK
fonte
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");
Никита Овчинников
fonte
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.

Emmanuel de Carvalho Garcia
fonte
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;
}
Priya
fonte
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.

pymarco
fonte
1
function in_array(needle, haystack){

    return haystack.indexOf(needle) !== -1;
}
crisswalt
fonte
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

Bogdan D
fonte
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 :-)

MageParts
fonte