Como posso verificar se um array inclui um valor em JavaScript?

Qual é a forma mais concisa e eficiente de descobrir se um array JavaScript contém um valor?

Esta é a única forma que conheço para o fazer:

function contains(a, obj) {
    for (var i = 0; i < a.length; i++) {
        if (a[i] === obj) {
            return true;
        }
    }
    return false;
}

Existe uma forma melhor e mais concisa de conseguir isto?

Isto está intimamente relacionado à questão Stack Overflow Melhor maneira de encontrar um item em um JavaScript Array? que trata de encontrar objetos em um array utilizando `indexOf'.

Atualização a partir de 2019: Esta resposta é de 2008 (11 anos!) e não é relevante para o uso moderno do JS. A melhoria de desempenho prometida foi baseada em um benchmark feito nos navegadores daquela época. Pode não ser relevante para os contextos modernos de execução do JS. Se você precisa de uma solução fácil, procure outras respostas. Se você precisa do melhor desempenho, faça um benchmark para si mesmo nos ambientes de execução relevantes.

Como outros disseram, a iteração através do array é provavelmente a melhor maneira, mas foi provado que um loop decrescente while é a maneira mais rápida de iterar em JavaScript. Portanto, você pode querer reescrever seu código da seguinte forma:

function contains(a, obj) {
    var i = a.length;
    while (i--) {
       if (a[i] === obj) {
           return true;
       }
    }
    return false;
}

Claro, mais vale estender o protótipo do Array:

Array.prototype.contains = function(obj) {
    var i = this.length;
    while (i--) {
        if (this[i] === obj) {
            return true;
        }
    }
    return false;
}

E agora você pode simplesmente usar o seguinte:

alert([1, 2, 3].contains(2)); // => true
alert([1, 2, 3].contains('2')); // => false
Comentários (16)

indexOf talvez, mas é uma "extensão JavaScript para o padrão ECMA-262; como tal, pode não estar presente em outras implementações do padrão".

Exemplo:

[1, 2, 3].indexOf(1) => 0
["foo", "bar", "baz"].indexOf("bar") => 1
[1, 2, 3].indexOf(4) => -1

AFAICS Microsoft não oferece algum tipo de alternativa a isto, mas você pode adicionar funcionalidades similares a arrays no Internet Explorer (e outros navegadores que não suportam indexOf) se você quiser, como uma rápida busca no Google revela (por exemplo, este).

Comentários (4)

Se você estiver usando JavaScript 1.6 ou posterior (Firefox 1.5 ou posterior) você pode usar Array.indexOf. Caso contrário, eu acho que você vai acabar com algo semelhante ao seu código original.

Comentários (0)