Como determinar se a matriz de JavaScript contém um object com um atributo que é igual a um determinado valor?

Eu tenho uma matriz como

vendors = [ { Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' } and so on... ]; 

Como faço para verificar esta matriz para ver se Magenic existe? Eu não quero fazer um loop, a menos que seja necessário. Estou trabalhando potencialmente com um par de mil registros.

ATUALIZADA

Como esse é um post popular, pensei em compartilhar algo novo que encontrei. E parece que @CAFxX já compartilhou isso! Eu deveria ler isso com mais frequência. Eu me deparei com https://benfrain.com/understanding-native-javascript-array-methods/ .

 vendors.filter(function(vendor){ return vendor.Name === "Magenic" }); 

E com o ECMAScript 2015 é ainda mais simples usar as novas funções de seta:

 vendors.filter(vendor => (vendor.Name === "Magenic")); 

Não há uma maneira “mágica” de verificar algo em uma matriz sem um loop. Mesmo se você usar alguma function, a function em si usará um loop. O que você pode fazer é sair do loop assim que encontrar o que procura para minimizar o tempo computacional.

 var found = false; for(var i = 0; i < vendors.length; i++) { if (vendors[i].Name == 'Magenic') { found = true; break; } } 

Não há necessidade de reinventar o roda loop, pelo menos não explicitamente (usando funções de seta , somente navegadores modernos ):

 if (vendors.filter(e => e.name === 'Magenic').length > 0) { /* vendors contains the element we're looking for */ } 

ou melhor ainda :

 if (vendors.some(e => e.name === 'Magenic')) { /* vendors contains the element we're looking for */ } 

EDIT: Se você precisar de compatibilidade com navegadores ruins, sua melhor aposta é:

 if (vendors.filter(function(e) { return e.name === 'Magenic'; }).length > 0) { /* vendors contains the element we're looking for */ } 

A resposta aceita ainda funciona, mas agora temos um método nativo do ECMAScript 6 [Array.find][1] para obter o mesmo efeito.

Citando MDN:

O método find () retorna o valor do primeiro elemento na matriz que satisfaz a function de teste fornecida. Caso contrário, indefinido é retornado.

 var arr = []; var item = { id: '21', step: 'step2', label: 'Banana', price: '19$' }; arr.push(item); /* note : data is the actual object that matched search criteria or undefined if nothing matched */ var data = arr.find( function( ele ) { return ele.id === '21'; } ); if( data ) { console.log( 'found' ); console.log(data); // This is entire object ie `item` not boolean } 

Veja o meu link jsfiddle Existe um polyfill para o IE fornecido pelo mozilla

Nenhum laço necessário. Três methods que vêm à mente:

Array.prototype.some ()

Esta é a resposta mais exata para a sua pergunta, ou seja, “verifique se algo existe”, o que implica um resultado bool. Isso será verdade se houver algum object ‘Magenic’, caso contrário, false:

 let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' ) 

Array.prototype.filter ()

Isso retornará uma matriz de todos os objects ‘Magenic’, mesmo se houver apenas um (retornará uma matriz de um elemento):

 let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' ) 

Se você tentar coagir isso para um booleano, ele não funcionará, já que uma matriz vazia (sem objects ‘Magenic’) ainda é muito importante. Então apenas use magenicVendors.length na sua condição.

Array.prototype.find ()

Isso retornará o primeiro object ‘Magenic’ (ou undefined se não houver nenhum):

 let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' ); 

Isso coage a um booleano bem (qualquer object é verdadeiro, undefined é falso).


Nota: Estou usando o fornecedor [“Name”] em vez de vendor.Name por causa do estranho case dos nomes das propriedades.

Nota 2: Nenhuma razão para usar igualdade solta (==) em vez de igualdade estrita (===) ao verificar o nome.

A menos que você queira reestruturá-lo assim:

 vendors = { Magenic: { Name: 'Magenic', ID: 'ABC' }, Microsoft: { Name: 'Microsoft', ID: 'DEF' } and so on... }; 

para o qual você pode fazer if(vendors.Magnetic)

Você terá que fazer um loop

De acordo com a especificação do ECMAScript 6, você pode usar o findIndex .

const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');

magenicIndex conterá 0 (que é o índice na matriz) ou -1 se não foi encontrado.

Você não pode sem olhar para o object realmente.

Você provavelmente deve mudar sua estrutura um pouco, como

 vendors = { Magenic: 'ABC', Microsoft: 'DEF' }; 

Então você pode apenas usá-lo como um hash de pesquisa.

 vendors['Microsoft']; // 'DEF' vendors['Apple']; // undefined 

Você tem que fazer um loop, não há maneira de contornar isso.

 function seekVendor(vendors, name) { for (var i=0, l=vendors.length; i 

Claro que você poderia usar uma biblioteca como linq.js para tornar isso mais agradável:

 Enumerable.From(vendors).Where("$.Name == 'Magenic'").First(); 

(veja jsFiddle para uma demonstração)

Eu duvido que o linq.js seja mais rápido do que um loop direto, mas certamente é mais flexível quando as coisas ficam um pouco mais complicadas.

Se você estiver usando o jquery, você pode aproveitar o grep para criar um array com todos os objects correspondentes:

 var results = $.grep(vendors, function (e) { return e.Name == "Magenic"; }); 

e, em seguida, use a matriz de resultados:

 for (var i=0, l=results.length; i 

Você pode usar o lodash . Se a biblioteca da lodash for muito pesada para sua aplicação, considere usar a function desnecessária não utilizada.

 let newArray = filter(_this.props.ArrayOne, function(item) { return find(_this.props.ArrayTwo, {"speciesId": item.speciesId}); }); 

Esta é apenas uma maneira de fazer isso. Outro pode ser:

 var newArray= []; _.filter(ArrayOne, function(item) { return AllSpecies.forEach(function(cItem){ if (cItem.speciesId == item.speciesId){ newArray.push(item); } }) }); 

console.log(arr);

O exemplo acima também pode ser reescrito sem usar nenhuma biblioteca como:

 var newArray= []; ArrayOne.filter(function(item) { return ArrayTwo.forEach(function(cItem){ if (cItem.speciesId == item.speciesId){ newArray.push(item); } }) }); console.log(arr); 

Espero que minha resposta ajude.

Me corrija se eu estiver errado … eu poderia ter usado forEach método desse forEach ,

 var found=false; vendors.forEach(function(item){ if(item.name === "name"){ found=true; return; } }); 

Hoje em dia eu estou acostumado com isso, por causa da simplicidade e da palavra autoexplicativa. Obrigado.

Alternativamente, você pode fazer:

 const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle)); 

var without2 = (arr, args) => arr.filter(v => v.id !== args.id); Exemplo:

without2([{id:1},{id:1},{id:2}],{id:2})

Resultado: sem2 ([{id: 1}, {id: 1}, {id: 2}], {id: 2})

Muitas respostas aqui são boas e muito fáceis. Mas se sua matriz de objects está tendo um conjunto fixo de valor, então você pode usar o truque abaixo:

Mapeie todo o nome em um object.

 vendors = [ { Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' } ]; var dirtyObj = {} for(var count=0;count 

Agora este dirtyObj você pode usar de novo e de novo sem qualquer loop.

 if(dirtyObj[vendor.Name]){ console.log("Hey! I am available."); } 

Como o OP fez a pergunta se a chave existe ou não . A solução proposta retornará um array com o object ou um array vazio se usarmos arr.filter como proposto em várias soluções acima.

Uma solução mais elegante que retornará booleano usando a function de filtro ES6 pode ser

 const magenicVendorExists = !!vendors.filter(vendor => (vendor.Name === "Magenic")); 

Nota: o primeiro ! irá converter o array vazio para true e um array com o object para false. Daí um ! em ! irá reverter o booleano.

Espero que ajude para uma implementação de código melhor e mais limpa

Eu preferiria ir com regex.

Se o seu código é o seguinte,

 vendors = [ { Name: 'Magenic', ID: 'ABC' }, { Name: 'Microsoft', ID: 'DEF' } ]; 

eu recomendaria

 /"Name":"Magenic"/.test(JSON.stringify(vendors))