Ich habe ein Array wie
vendors = [
{
Name: 'Magenic',
ID: 'ABC'
},
{
Name: 'Microsoft',
ID: 'DEF'
} and so on...
];
Wie überprüfe ich dieses Array, um festzustellen, ob Magenic existiert? Ich möchte keine Schleife, es sei denn, ich muss. Ich arbeite mit möglicherweise ein paar tausend Datensätzen.
AKTUALISIERTE
Da dies ein beliebter Beitrag war, dachte ich, ich würde etwas Neues mitteilen, was ich gefunden habe. Und es scheint, dass @CAFxX dies bereits geteilt hat! Ich sollte diese öfter lesen. Ich bin auf https://benfrain.com/understanding-native-javascript-array-methods/ gestoßen.
vendors.filter(function(vendor){ return vendor.Name === "Magenic" });
Mit ECMAScript 2015 ist es noch einfacher mit den neuen Pfeilfunktionen:
vendors.filter(vendor => (vendor.Name === "Magenic"));
2018 edit: Diese Antwort stammt aus dem Jahr 2011, bevor die Browser Array-Methoden und Pfeilfunktionen weitgehend unterstützt haben. Schauen Sie sich die Antwort von CAFxX an.
Es gibt keine "magische" Möglichkeit, etwas in einem Array ohne Schleife zu überprüfen. Selbst wenn Sie eine Funktion verwenden, verwendet die Funktion selbst eine Schleife. Was Sie tun können, ist, die Schleife zu verlassen, sobald Sie gefunden haben, wonach Sie suchen, um die Rechenzeit zu minimieren.
var found = false;
for(var i = 0; i < vendors.length; i++) {
if (vendors[i].Name == 'Magenic') {
found = true;
break;
}
}
Keine Notwendigkeit, das neu zu erfinden rad Schleife, zumindest nicht explizit (mit Pfeilfunktionen , nur modernen Browsern ):
if (vendors.filter(e => e.name === 'Magenic').length > 0) {
/* vendors contains the element we're looking for */
}
oder besser noch:
if (vendors.some(e => e.name === 'Magenic')) {
/* vendors contains the element we're looking for */
}
BEARBEITEN: Wenn Sie Kompatibilität mit miesen Browsern benötigen, ist Ihre beste Wette:
if (vendors.filter(function(e) { return e.name === 'Magenic'; }).length > 0) {
/* vendors contains the element we're looking for */
}
Keine Schleife notwendig Drei Methoden, die mir in den Sinn kommen:
Array.prototype.some ()
Dies ist die genaueste Antwort auf Ihre Frage, d. H. "Prüfen Sie, ob etwas existiert", was ein bool-Ergebnis impliziert. Dies ist wahr, wenn es 'Magenic'-Objekte gibt, andernfalls false:
let hasMagenicVendor = vendors.some( vendor => vendor['Name'] === 'Magenic' )
Array.prototype.filter ()
Dadurch wird ein Array aller 'Magenic'-Objekte zurückgegeben, auch wenn nur eines vorhanden ist (ein Array mit einem Element wird zurückgegeben):
let magenicVendors = vendors.filter( vendor => vendor['Name'] === 'Magenic' )
Wenn Sie versuchen, dies zu einem Boolean zu erzwingen, funktioniert es nicht, da ein leeres Array (keine 'Magenic'-Objekte) immer noch wahr ist. Verwenden Sie also einfach magenicVendors.length
in Ihrer Bedingung.
Array.prototype.find ()
Dies gibt das erste 'Magenic'-Objekt zurück (oder undefined
, falls es keine gibt):
let magenicVendor = vendors.find( vendor => vendor['Name'] === 'Magenic' );
Dies zwingt zu einem booleschen OK (jedes Objekt ist wahr, undefined
ist falsch).
Hinweis: Ich verwende Verkäufer ["Name"] anstelle von Hersteller.Name wegen des seltsamen Gehäuses der Eigenschaftsnamen.
Anmerkung 2: Kein Grund, lose Gleichheit (==) anstelle strenger Gleichheit (===) bei der Überprüfung des Namens zu verwenden.
Die akzeptierte Antwort funktioniert immer noch, aber jetzt haben wir eine native ECMAScript 6-Methode [Array.find][1]
, um den gleichen Effekt zu erzielen.
Zitat MDN:
Die find () -Methode gibt den Wert des ersten Elements im Array zurück das erfüllt die bereitgestellte Testfunktion. Ansonsten undefined ist ist zurückgekommen.
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
}
Siehe mein jsfiddle link Es gibt eine Polyfill für IE , die von mozilla bereitgestellt wird
Gemäß ECMAScript 6-Spezifikation können Sie findIndex
verwenden.
const magenicIndex = vendors.findIndex(vendor => vendor.Name === 'Magenic');
magenicIndex
hält entweder 0
(das ist der Index im Array) oder -1
wenn es nicht gefunden wurde.
Wenn Sie es nicht so strukturieren wollen:
vendors = {
Magenic: {
Name: 'Magenic',
ID: 'ABC'
},
Microsoft: {
Name: 'Microsoft',
ID: 'DEF'
} and so on...
};
wozu kannst du if(vendors.Magnetic)
Du musst eine Schleife machen
Sie können nicht ohne wirklich in das Objekt schauen.
Sie sollten wahrscheinlich Ihre Struktur ein wenig ändern, wie
vendors = {
Magenic: 'ABC',
Microsoft: 'DEF'
};
Dann können Sie es einfach als Lookup-Hash verwenden.
vendors['Microsoft']; // 'DEF'
vendors['Apple']; // undefined
Da hat das OP die Frage gestellt ob der Schlüssel existiert oder nicht .
Eine elegantere Lösung, die mit der ES6-Reduzierfunktion boolesche Werte liefert, kann sein
const magenicVendorExists = vendors.reduce(vendor => (vendor.Name === "Magenic"), false);
Hinweis: Der anfängliche Parameter für das Verkleinern ist eine false
. Wenn das Array den Schlüssel hat, wird es true zurückgegeben.
Hoffe, es hilft für eine bessere und sauberere Code-Implementierung
So würde ich es machen
const found = vendors.some(item => item.Name === 'Magenic');
Die array.some()
-Methode prüft, ob in einem Array mindestens ein Wert vorhanden ist, der den Kriterien entspricht und einen booleschen Wert zurückgibt. Von hier aus können Sie gehen mit:
if (found) {
// do something
} else {
// do something else
}
Du musst eine Schleife machen, da gibt es keinen Weg.
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];
}
}
}
Natürlich könnten Sie eine Bibliothek wie linq.js verwenden, um dies angenehmer zu gestalten:
Enumerable.From(vendors).Where("$.Name == 'Magenic'").First();
(siehe jsFiddle für eine Demo)
Ich bezweifle, dass linq.js schneller ist als eine direkte Schleife, aber es ist sicherlich flexibler, wenn die Dinge etwas komplizierter werden.
wenn Sie Jquery verwenden, können Sie mit grep ein Array mit allen übereinstimmenden Objekten erstellen:
var results = $.grep(vendors, function (e) {
return e.Name == "Magenic";
});
und dann das Ergebnisfeld verwenden:
for (var i=0, l=results.length; i<l; i++) {
console.log(results[i].ID);
}
Sie können lodash verwenden. Wenn die lodash-Bibliothek für Ihre Anwendung zu umfangreich ist, sollten Sie in Betracht ziehen, unnötige Funktionen zu entfernen, die nicht verwendet werden.
let newArray = filter(_this.props.ArrayOne, function(item) {
return find(_this.props.ArrayTwo, {"speciesId": item.speciesId});
});
Dies ist nur eine Möglichkeit, dies zu tun. Ein anderer kann sein:
var newArray= [];
_.filter(ArrayOne, function(item) {
return AllSpecies.forEach(function(cItem){
if (cItem.speciesId == item.speciesId){
newArray.Push(item);
}
})
});
console.log(arr);
Das obige Beispiel kann auch ohne Verwendung von Bibliotheken neu geschrieben werden wie:
var newArray= [];
ArrayOne.filter(function(item) {
return ArrayTwo.forEach(function(cItem){
if (cItem.speciesId == item.speciesId){
newArray.Push(item);
}
})
});
console.log(arr);
Hoffe meine Antwort hilft.
Korrigieren Sie mich, wenn ich falsch liege .. Ich hätte die Methode forEach
so verwenden können,
var found=false;
vendors.forEach(function(item){
if(item.name === "name"){
found=true;
return;
}
});
Heutzutage bin ich daran gewöhnt, wegen Einfachheit und selbsterklärendem Wort.
Um ein Objekt mit einem anderen zu vergleichen, kombiniere ich eine for-Schleife (wird zum Durchlaufen von Objekten verwendet) und einige () . Sie müssen sich keine Gedanken darüber machen, dass ein Array die Grenzen überschreitet usw., so dass etwas Code gespeichert wird. Dokumentation zu .some finden Sie hier
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);
Eine alternative Möglichkeit, ein Objekt mit einem anderen zu vergleichen, besteht darin, eine verschachtelte for-Schleife mit Object.keys (). Length zu verwenden, um die Anzahl der Objekte im Array zu ermitteln. Code unten:
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);
Um Ihre genaue Frage zu beantworten, wenn Sie nur nach einem Wert in einem Objekt suchen, können Sie eine einzige for-Schleife verwenden.
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');
}
}
Sie können das für mich ausprobieren.
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 } ]
Mein Ansatz zur Lösung dieses Problems ist die Verwendung von ES6 und das Erstellen einer Funktion, die die Überprüfung für uns übernimmt. Der Vorteil dieser Funktion besteht darin, dass sie in Ihrem Projekt wiederverwendet werden kann, um jedes Array von Objekten zu überprüfen, für das die key
und die value
zu überprüfen sind.
GENUG GESPRÄCH, SEHEN SIE DEN CODE
Array
const ceos = [
{
name: "Jeff Bezos",
company: "Amazon"
},
{
name: "Mark Zuckerberg",
company: "Facebook"
},
{
name: "Tim Cook",
company: "Apple"
}
];
Funktion
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;
}
Anruf/Nutzung
const found = arrayIncludesInObj(ceos, "name", "Tim Cook"); // true
const found = arrayIncludesInObj(ceos, "name", "Tim Bezos"); // false
Alternativ können Sie Folgendes tun:
const find = (key, needle) => return !!~vendors.findIndex(v => (v[key] === needle));
var without2 = (arr, args) => arr.filter(v => v.id !== args.id);
Beispiel:
without2([{id:1},{id:1},{id:2}],{id:2})
Ergebnis: Without2 ([{id: 1}, {id: 1}, {id: 2}], {id: 2})
Viele Antworten sind gut und ziemlich einfach. Wenn Ihr Array von Objekten jedoch einen festen Wertesatz hat, können Sie den folgenden Trick verwenden:
Ordnen Sie den gesamten Namen in einem Objekt zu.
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.
}
Nun kann dieses dirtyObj immer wieder ohne Schleife verwendet werden.
if(dirtyObj[vendor.Name]){
console.log("Hey! I am available.");
}
JS Bietet Array-Funktionen, mit denen Sie dies relativ einfach erreichen können. Sie sind die folgenden:
Array.prototype.filter
: Nimmt eine Callback-Funktion, die ein Test ist, das Array wird dann mit is callback durchlaufen und nach diesem Callback gefiltert. Ein neues gefiltertes Array wird zurückgegeben.Array.prototype.some
: Nimmt eine Rückruffunktion an, die ein Test ist, das Array wird dann mit is callback durchlaufen und wenn ein Element den Test bestehtder boolesche Wert true wird zurückgegeben. Andernfalls false wird zurückgegebenDie Besonderheiten lassen sich am besten anhand eines Beispiels erklären:
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');
}
Diese 2 Funktionen sind ES6
, werden jedoch möglicherweise nicht von allen Browsern unterstützt. Um dies zu überwinden, können Sie eine Polyfüllung verwenden. Hier ist die Polyfüllung für Array.prototype.some
(von 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;
};
}