J'ai un tableau comme
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
} and so on...
];
Comment vérifier ce tableau pour voir si Magenic existe? Je ne veux pas faire de boucle, à moins d'y être obligé. Je travaille avec potentiellement quelques milliers de disques.
MIS À JOUR
Comme cela a été un post populaire, j'ai pensé partager quelque chose de nouveau que j'ai trouvé. Et il semble que @CAFxX l’ait déjà partagé! Je devrais les lire plus souvent. Je suis tombé sur https://benfrain.com/understanding-native-javascript-array-methods/ .
vendors.filter(function(vendor){ return vendor.Name === "Magenic" });
Et avec ECMAScript 2015, l'utilisation des nouvelles fonctions de flèche est encore plus simple:
vendors.filter(vendor => (vendor.Name === "Magenic"));
2018 edit: cette réponse date de 2011, avant que les navigateurs ne prennent largement en charge les méthodes de filtrage par tableaux et les fonctions de flèche. Jetez un coup d'œil à La réponse de CAFxX .
Il n'y a pas de moyen "magique" de vérifier quelque chose dans un tableau sans boucle. Même si vous utilisez une fonction, la fonction elle-même utilisera une boucle. Ce que vous pouvez faire est de sortir de la boucle dès que vous trouvez ce que vous cherchez pour réduire le temps de calcul.
var found = false;
for(var i = 0; i < vendors.length; i++) {
if (vendors[i].Name == 'Magenic') {
found = true;
break;
}
}
Pas besoin de réinventer le roue boucle, du moins pas explicitement (avec fonctions de flèche , navigateurs modernes uniquement ):
if (vendors.filter(e => e.name === 'Magenic').length > 0) {
/* vendors contains the element we're looking for */
}
ou mieux encore:
if (vendors.some(e => e.name === 'Magenic')) {
/* vendors contains the element we're looking for */
}
EDIT: Si vous avez besoin de compatibilité avec les mauvais navigateurs, votre meilleur pari est:
if (vendors.filter(function(e) { return e.name === 'Magenic'; }).length > 0) {
/* vendors contains the element we're looking for */
}
Aucune boucle nécessaire. Trois méthodes qui me viennent à l’esprit:
Array.prototype.some ()
C’est la réponse la plus exacte à votre question, c’est-à-dire "vérifier si quelque chose existe", ce qui implique un résultat boolé. Cela sera vrai s'il y a des objets 'Magenic', faux sinon:
let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )
Array.prototype.filter ()
Cela retournera un tableau de tous les objets 'Magenic', même s'il n'y en a qu'un (retournera un tableau d'un élément):
let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )
Si vous essayez de contraindre cela à un booléen, cela ne fonctionnera pas, car un tableau vide (pas d'objets 'Magenic') est toujours la vérité. Donc, utilisez simplement magenicVendors.length
dans votre conditionnel.
Array.prototype.find ()
Cela retournera le premier objet 'Magenic' (ou undefined
s'il n'y en a pas):
let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );
Ceci oblige à un booléen correct (tout objet est la vérité, undefined
est la fausseté).
Remarque: J'utilise fournisseur ["Nom"] au lieu de fournisseur.Nom en raison de l'étrange casse des noms de propriété.
Remarque 2: Aucune raison d'utiliser l'égalité en vrac (==) au lieu d'une égalité stricte (===) lors de la vérification du nom.
La réponse acceptée fonctionne toujours, mais nous avons maintenant une méthode native ECMAScript 6 [Array.find][1]
pour obtenir le même effet.
Citant MDN:
La méthode find () renvoie la valeur du premier élément du tableau qui satisfait à la fonction de test fournie. Sinon, non défini est revenu.
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 i.e. `item` not boolean
}
Voir mon lien jsfiddle Il existe un polyfill pour IE fourni par mozilla
À moins que vous ne vouliez le restructurer comme ceci:
vendors = {
Magenic: {
Name: 'Magenic',
ID: 'ABC'
},
Microsoft: {
Name: 'Microsoft',
ID: 'DEF'
} and so on...
};
auquel vous pouvez faire if(vendors.Magnetic)
Vous devrez faire une boucle
Vous ne pouvez pas sans regarder vraiment dans l'objet.
Vous devriez probablement changer un peu votre structure, comme
vendors = {
Magenic: 'ABC',
Microsoft: 'DEF'
};
Ensuite, vous pouvez simplement l'utiliser comme une recherche.
vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined
Comme le PO a posé la question si la clé existe ou non .
Une solution plus élégante qui rendra booléen en utilisant la fonction de réduction ES6 peut être
const magenicVendorExists = vendors.reduce(vendor => (vendor.Name === "Magenic"), false);
Remarque: Le paramètre initial de reduction est false
et si le tableau a la clé, il retournera la valeur true.
J'espère que cela aidera à une implémentation de code meilleure et plus propre
Voici comment je le ferais
const found = vendors.some(item => item.Name === 'Magenic');
La méthode array.some()
vérifie s'il existe au moins une valeur dans un tableau qui correspond aux critères et renvoie un booléen. A partir de là, vous pouvez aller avec:
if (found) {
// do something
} else {
// do something else
}
Vous devez faire une boucle, il n'y a pas moyen de le contourner.
function seekVendor(vendors, name) {
for (var i=0, l=vendors.length; i<l; i++) {
if (typeof vendors[i] == "object" && vendors[i].Name === name) {
return vendors[i];
}
}
}
Bien sûr, vous pouvez utiliser une bibliothèque comme linq.js pour rendre cela plus agréable:
Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();
(voir jsFiddle pour une démo)
Je doute que linq.js soit plus rapide qu'une boucle simple, mais il est certainement plus flexible lorsque les choses deviennent un peu plus compliquées.
si vous utilisez jquery, vous pouvez tirer parti de grep pour créer un tableau avec tous les objets correspondants:
var results = $.grep(vendors, function (e) {
return e.Name == "Magenic";
});
puis utilisez le tableau de résultats:
for (var i=0, l=results.length; i<l; i++) {
console.log(results[i].ID);
}
Corrigez-moi si je me trompe ... j'aurais pu utiliser la méthode forEach
comme celle-ci,
var found=false;
vendors.forEach(function(item){
if(item.name === "name"){
found=true;
return;
}
});
De nos jours, je suis habitué à cela, à cause de sa simplicité et de son caractère explicite Word ..__ Merci.
Pour comparer un objet à un autre, je combine une boucle for in (utilisée pour parcourir des objets) et un peu () . Vous n'avez pas à vous soucier d'un tableau qui sort des limites, etc., de manière à enregistrer du code. La documentation sur .some peut être trouvée ici
var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];
var objectsFound = [];
for(let objectNumber in productList){
var currentId = productList[objectNumber].id;
if (theDatabaseList.some(obj => obj.id === currentId)) {
// Do what you need to do with the matching value here
objectsFound.Push(currentId);
}
}
console.log(objectsFound);
Une autre manière de comparer un objet à un autre consiste à utiliser une boucle for imbriquée avec Object.keys (). Length pour obtenir la quantité d'objets dans le tableau. Code ci-dessous:
var productList = [{id: 'text3'}, {id: 'text2'}, {id: 'text4', product: 'Shampoo'}]; // Example of selected products
var theDatabaseList = [{id: 'text1'}, {id: 'text2'},{id: 'text3'},{id:'text4', product: 'shampoo'}];
var objectsFound = [];
for(var i = 0; i < Object.keys(productList).length; i++){
for(var j = 0; j < Object.keys(theDatabaseList).length; j++){
if(productList[i].id === theDatabaseList[j].id){
objectsFound.Push(productList[i].id);
}
}
}
console.log(objectsFound);
Pour répondre à votre question exacte, si vous recherchez simplement une valeur dans un objet, vous pouvez utiliser une boucle unique for in.
var vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
for(var ojectNumbers in vendors){
if(vendors[ojectNumbers].Name === 'Magenic'){
console.log('object contains Magenic');
}
}
Vous pouvez essayer cela son travail pour moi.
const _ = require('lodash');
var arr = [
{
name: 'Jack',
id: 1
},
{
name: 'Gabriel',
id: 2
},
{
name: 'John',
id: 3
}
]
function findValue(value) {
return _.filter(arr, function (object) {
return object['name'].toLowerCase().indexOf(value.toLowerCase()) >= 0;
});
}
console.log(findValue('jack'))
//[ { name: 'Jack', id: 1 } ]
Mon approche pour résoudre ce problème consiste à utiliser ES6 et à créer une fonction qui effectue la vérification pour nous. L'avantage de cette fonction est qu'elle peut être réutilisée dans votre projet pour vérifier n'importe quel tableau d'objets à l'aide des variables key
et value
à vérifier.
Assez parler, voyons le code
Tableau
const ceos = [
{
name: "Jeff Bezos",
company: "Amazon"
},
{
name: "Mark Zuckerberg",
company: "Facebook"
},
{
name: "Tim Cook",
company: "Apple"
}
];
Une fonction
const arrayIncludesInObj = (arr, key, valueToCheck) => {
let found = false;
arr.some(value => {
if (value[key] === valueToCheck) {
found = true;
return true; // this will break the loop once found
}
});
return found;
}
Appel/Utilisation
const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true
const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false
Sinon, vous pouvez faire:
const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle));
var without2 = (arr, args) => arr.filter(v => v.id !== args.id);
.__ Exemple:
without2([{id:1},{id:1},{id:2}],{id:2})
Résultat: Sans2 ([{id: 1}, {id: 1}, {id: 2}], {id: 2})
Beaucoup de réponses ici sont bonnes et assez faciles. Mais si votre tableau d'objets a un ensemble de valeurs fixe, vous pouvez utiliser l'astuce suivante:
Mappez tout le nom dans un objet.
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
}
];
var dirtyObj = {}
for(var count=0;count<vendors.length;count++){
dirtyObj[vendors[count].Name] = true //or assign which gives you true.
}
Maintenant, ce dirtyObj, vous pouvez utiliser encore et encore sans aucune boucle.
if(dirtyObj[vendor.Name]){
console.log("Hey! I am available.");
}
JS offre des fonctions de tableau qui vous permettent d'y parvenir relativement facilement. Ils sont les suivants:
Array.prototype.filter
: Prend une fonction de rappel qui est un test, le tableau est ensuite itéré sur son rappel et filtré en fonction de ce rappel. n nouveau tableau filtré est retourné.Array.prototype.some
: Prend une fonction de rappel qui est un test, le tableau est ensuite itéré sur son rappel et si un élément réussit le test,le booléen true est renvoyé. Sinon false est retournéLes détails sont mieux expliqués via un exemple:
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
} //and so on goes array...
];
// filter returns a new array, we instantly check if the length
// is longer than zero of this newly created array
if (vendors.filter(company => company.Name === 'Magenic').length ) {
console.log('I contain Magenic');
}
// some would be a better option then filter since it directly returns a boolean
if (vendors.some(company => company.Name === 'Magenic')) {
console.log('I also contain Magenic');
}
Ces 2 fonctions sont ES6
, tous les navigateurs ne les prennent pas en charge. Pour surmonter cela, vous pouvez utiliser un polyfill. Voici le polyfill pour Array.prototype.some
(de MDN):
if (!Array.prototype.some) {
Array.prototype.some = function(fun, thisArg) {
'use strict';
if (this == null) {
throw new TypeError('Array.prototype.some called on null or undefined');
}
if (typeof fun !== 'function') {
throw new TypeError();
}
var t = Object(this);
var len = t.length >>> 0;
for (var i = 0; i < len; i++) {
if (i in t && fun.call(thisArg, t[i], i, t)) {
return true;
}
}
return false;
};
}