Come determinare se l’array Javascript contiene un object con un attributo uguale a un determinato valore?

Ho un array come

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

Come posso controllare questo array per vedere se Magenic esiste? Non voglio fare il ciclo, a meno che non sia necessario. Sto lavorando con potenzialmente un paio di migliaia di dischi.

AGGIORNATO

Dato che questo è stato un post popolare, ho pensato di condividere qualcosa di nuovo che ho trovato. E sembra che @CAFxX lo abbia già condiviso! Dovrei leggere questi più spesso. Mi sono imbattuto in https://benfrain.com/understanding-native-javascript-array-methods/ .

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

E con ECMAScript 2015 è ancora più semplice utilizzare le nuove funzioni di freccia:

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

Non esiste un modo “magico” per controllare qualcosa in un array senza loop. Anche se si utilizza una funzione, la funzione stessa utilizzerà un ciclo. Quello che puoi fare è uscire dal ciclo non appena trovi ciò che stai cercando per ridurre al minimo il tempo di calcolo.

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

Non c’è bisogno di reinventare il ruota loop, almeno non esplicitamente (usando le funzioni freccia , solo i browser moderni ):

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

o, meglio ancora :

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

EDIT: Se hai bisogno di compatibilità con browser scadenti, la soluzione migliore è:

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

La risposta accettata funziona ancora, ma ora abbiamo un metodo nativo ECMAScript 6 [Array.find][1] per ottenere lo stesso effetto.

Citando MDN:

Il metodo find () restituisce il valore del primo elemento dell’array che soddisfa la funzione di test fornita. Altrimenti viene restituito undefined.

 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 } 

Vedi il mio link jsfiddle C’è un polyfill per IE fornito da mozilla

Nessun ciclo necessario. Tre metodi che vengono in mente:

Array.prototype.some ()

Questa è la risposta più esatta per la tua domanda, cioè “controlla se qualcosa esiste”, che implica un risultato bool. Questo sarà vero se ci sono oggetti “Magenici”, altrimenti falso:

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

Array.prototype.filter ()

Ciò restituirà un array di tutti gli oggetti ‘Magenic’, anche se ce n’è uno solo (restituirà un array di un elemento):

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

Se provi a forzare questo ad un booleano, non funzionerà, dato che un array vuoto (senza oggetti ‘Magenic’) è ancora vero. Quindi usa solo magenicVendors.length nel tuo condizionale.

Array.prototype.find ()

Ciò restituirà il primo object ‘Magenic’ (o undefined se undefined ce n’è uno):

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

Ciò costringe a un valore booleano okay (qualsiasi object è vero, undefined è falso).


Nota: sto utilizzando il fornitore [“Nome”] al posto di vendor.Name a causa dello strano involucro dei nomi delle proprietà.

Nota 2: nessun motivo per utilizzare l’uguaglianza libera (==) anziché l’uguaglianza rigorosa (===) quando si controlla il nome.

A meno che tu non voglia ristrutturarlo in questo modo:

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

a cui puoi fare if(vendors.Magnetic)

Dovrai fare un ciclo

Come da specifiche ECMAScript 6, puoi usare findIndex .

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

magenicIndex manterrà 0 (che è l’indice dell’array) o -1 se non è stato trovato.

Non puoi senza guardare veramente l’object.

Probabilmente dovresti cambiare la tua struttura un po ‘, come

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

Quindi puoi semplicemente usarlo come un look-hash.

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

Devi andare in loop, non c’è modo di aggirarlo.

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

Ovviamente potresti usare una libreria come linq.js per rendere questo più piacevole:

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

(vedi jsFiddle per una demo)

Dubito che linq.js sarà più veloce di un ciclo straight-forward, ma sicuramente è più flessibile quando le cose diventano un po 'più complicate.

se usi jquery puoi sfruttare grep per creare una matrice con tutti gli oggetti corrispondenti:

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

e quindi utilizzare l’array di risultati:

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

Puoi usare lodash . Se la libreria di lodash è troppo pesante per la tua applicazione, considera la possibilità di escludere funzioni inutili non utilizzate.

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

Questo è solo un modo per farlo. Un altro può essere:

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

console.log(arr);

L’esempio sopra può anche essere riscritto senza utilizzare alcuna libreria come:

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

Spero che la mia risposta aiuti.

Correggimi se ho torto. forEach potuto usare forEach metodo come questo,

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

Oggi mi sono abituato, per via della sua semplicità e della sua parola autoesplicativa. Grazie.

In alternativa puoi fare:

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

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

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

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

Molte risposte qui sono buone e abbastanza facili. Ma se la tua matrice di oggetti ha un set di valori fisso, puoi usare il seguente trucco:

Mappare tutto il nome in un object.

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

Ora questo dirtyObj puoi usare ancora e ancora senza loop.

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

Come l’OP ha posto la domanda se la chiave esiste o no . La soluzione proposta restituirà un array con l’object o un array vuoto se usiamo arr.filter come proposto in diverse soluzioni sopra.

Una soluzione più elegante che restituirà booleana utilizzando la funzione di filtro ES6 può essere

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

Nota: il primo ! convertirà la matrice vuota in true e una matrice con object in false. Quindi a ! avanti ! ripristinerà il valore booleano.

Spero che aiuti a implementare un codice migliore e più pulito

Preferirei andare con regex.

Se il tuo codice è come segue,

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

io raccomanderei

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