Disons que j'ai un tableau de quatre objets:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
Est-il possible d'obtenir le troisième objet ({a: 5, b: 6}
) à l'aide de la valeur de la propriété b
, par exemple sans boucle for...in
?
Filter
tableau d'objets, dont la propriété correspond à valeur, retourne tableau:
var result = jsObjects.filter(obj => {
return obj.b === 6
})
Voir le Docs MDN sur Array.prototype.filter ()
const jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
]
let result = jsObjects.filter(obj => {
return obj.b === 6
})
console.log(result)
Find
la valeur du premier élément/objet du tableau, sinon undefined
est renvoyé.
var result = jsObjects.find(obj => {
return obj.b === 6
})
Voir le Docs MDN sur Array.prototype.find ()
const jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
]
let result = jsObjects.find(obj => {
return obj.b === 6
})
console.log(result)
jsObjects.find(x => x.b === 6)
De MDN:
La méthode
find()
renvoie une valeur dans le tableau, si un élément du tableau satisfait à la fonction de test fournie. Sinon,undefined
est renvoyé.
Remarque secondaire: les méthodes telles que find()
et les fonctions de flèche ne sont pas prises en charge par les anciens navigateurs (comme IE). Par conséquent, si vous souhaitez prendre en charge ces navigateurs, vous devez transpiler votre code avec Babel .
Je ne sais pas pourquoi vous êtes contre une boucle for (vraisemblablement vous vouliez dire une boucle for, pas spécifiquement pour..in), elles sont rapides et faciles à lire. Quoi qu'il en soit, voici quelques options.
Pour boucle:
function getByValue(arr, value) {
for (var i=0, iLen=arr.length; i<iLen; i++) {
if (arr[i].b == value) return arr[i];
}
}
.filtre
function getByValue2(arr, value) {
var result = arr.filter(function(o){return o.b == value;} );
return result? result[0] : null; // or undefined
}
.pour chaque
function getByValue3(arr, value) {
var result = [];
arr.forEach(function(o){if (o.b == value) result.Push(o);} );
return result? result[0] : null; // or undefined
}
Si, par contre, vous vouliez vraiment dire for..in et souhaitez rechercher un objet avec une propriété de valeur 6, vous devez utiliser for..in sauf si vous passez les noms à vérifier. par exemple.
function getByValue4(arr, value) {
var o;
for (var i=0, iLen=arr.length; i<iLen; i++) {
o = arr[i];
for (var p in o) {
if (o.hasOwnProperty(p) && o[p] == value) {
return o;
}
}
}
}
Try Array filter méthode pour filtrer le array of objects
avec property
.
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
en utilisant la méthode de filtrage de tableau:
var filterObj = jsObjects.filter(function(e) {
return e.b == 6;
});
utilisant pour la boucle d'entrée:
for (var i in jsObjects) {
if (jsObjects[i].b == 6) {
console.log(jsObjects[i]); // {a: 5, b: 6}
}
}
Le violon en marche:https://jsfiddle.net/uq9n9g77/
Utilisation de underscore.js:
var foundObject = _.findWhere(jsObjects, {b: 6});
Il semble que dans la proposition ECMAScript 6, il existe les méthodes Array
, find()
et findIndex()
. MDN propose également des polyfill que vous pouvez inclure pour obtenir la fonctionnalité de ceux-ci sur tous les navigateurs.
find()
:
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.log( [4, 6, 8, 12].find(isPrime) ); // undefined, not found
console.log( [4, 5, 8, 12].find(isPrime) ); // 5
function isPrime(element, index, array) {
var start = 2;
while (start <= Math.sqrt(element)) {
if (element % start++ < 1) return false;
}
return (element > 1);
}
console.log( [4, 6, 8, 12].findIndex(isPrime) ); // -1, not found
console.log( [4, 6, 7, 12].findIndex(isPrime) ); // 2
Si je comprends bien, vous voulez trouver l’objet dans le tableau dont la propriété b
est 6
?
var found;
jsObjects.some(function (obj) {
if (obj.b === 6) {
found = obj;
return true;
}
});
Ou si vous utilisiez un trait de soulignement:
var found = _.select(jsObjects, function (obj) {
return obj.b === 6;
});
OK, il y a peu de façons de le faire, mais commençons par la plus simple et la plus récente des méthodes, cette fonction s'appelle find()
.
Faites attention quand vous utilisez find
car même IE11 ne le supporte pas, il doit donc être transpilé ...
alors vous avez cet objet comme vous l'avez dit:
var jsObjects = [
{a: 1, b: 2},
{a: 3, b: 4},
{a: 5, b: 6},
{a: 7, b: 8}
];
et vous pouvez écrire une fonction et l'obtenir comme ceci:
function filterValue(obj, key, value) {
return obj.find(function(v){ return v[key] === value});
}
et utilisez la fonction comme ceci:
filterValue(jsObjects, "b", 6); //{a: 5, b: 6}
Aussi dans ES6 pour même la version abrégée:
const filterValue = (obj, key, value)=> obj.find(v => v[key] === value);
Cette méthode ne renvoie que la première valeur qui correspond ... Pour une meilleure prise en charge des résultats et du navigateur, vous pouvez utiliser filter
:
const filterValue = (obj, key, value)=> obj.filter(v => v[key] === value);
et nous retournerons [{a: 5, b: 6}]
...
Cette méthode retournera un tableau à la place ...
Vous utilisez aussi très simplement boucle, créez une fonction comme celle-ci:
function filteredArray(arr, key, value) {
const newArray = [];
for(i=0, l=arr.length; i<l; i++) {
if(arr[i][key] === value) {
newArray.Push(arr[i]);
}
}
return newArray;
}
et appelez ça comme ça:
filteredArray(jsObjects, "b", 6); //[{a: 5, b: 6}]
Si vous recherchez un seul résultat plutôt qu'un tableau, puis-je suggérer de réduire?
Voici une solution en clair 'ole javascript qui retourne un objet correspondant s'il en existe un ou null si ce n'est pas le cas.
var result = arr.reduce(function(prev, curr) { return (curr.b === 6) ? curr : prev; }, null);
Pourquoi ne pas utiliser _.find(collection, [predicate=_.identity], [fromIndex=0])
de lo-dash pour obtenir un objet à partir d’un tableau d’objets par valeur de propriété d’objet. Vous pouvez faire quelque chose comme ça:
var o = _.find(jsObjects, {'b': 6});
Arguments:
collection (Array|Object): The collection to inspect.
[predicate=_.identity] (Function): The function invoked per iteration.
[fromIndex=0] (number): The index to search from.
Résultats
(*): Returns the matched element (in your case, {a: 5, b: 6}), else undefined.
En termes de performances, _.find()
est plus rapide car il extrait uniquement le premier objet avec la propriété {'b': 6}
. Par contre, si supposons que votre tableau contienne plusieurs objets avec un ensemble de propriétés correspondant (clé: valeur), vous devriez envisager d'utiliser la méthode _.filter()
. Donc dans votre cas, comme votre tableau a un seul objet avec cette propriété, je voudrais utiliser _.find()
.
Vous pouvez l'utiliser avec la fonction de flèche comme ci-dessous:
var demoArray = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
var result = demoArray.filter( obj => obj.name === 'apples')[0];
console.log(result);
// {name: 'apples', quantity: 2}
Voir cette documentation https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_objects/Object/values
Exemple :
var inventory = [
{name: 'apples', quantity: 2},
{name: 'bananas', quantity: 0},
{name: 'cherries', quantity: 5}
];
function findCherries(fruit) {
return fruit.name === 'cherries';
}
console.log(inventory.find(findCherries));
// { name: 'cherries', quantity: 5 }
Juste amélioré la partie la plus rapide/meilleure de cette réponse pour être plus réutilisable/plus clair:
function getElByPropVal(arr, prop, val){
for (var i = 0, length = arr.length; i < length; i++) {
if (arr[i][prop] == val){
return arr[i];
}
}
}
Pour obtenir le premier objet d'un tableau d'objets avec une valeur de propriété spécifique:
function getObjectFromObjectsArrayByPropertyValue(objectsArray, propertyName, propertyValue) {
return objectsArray.find(function (objectsArrayElement) {
return objectsArrayElement[propertyName] == propertyValue;
});
}
function findObject () {
var arrayOfObjectsString = document.getElementById("arrayOfObjects").value,
arrayOfObjects,
propertyName = document.getElementById("propertyName").value,
propertyValue = document.getElementById("propertyValue").value,
preview = document.getElementById("preview"),
searchingObject;
arrayOfObjects = JSON.parse(arrayOfObjectsString);
console.debug(arrayOfObjects);
if(arrayOfObjects && propertyName && propertyValue) {
searchingObject = getObjectFromObjectsArrayByPropertyValue(arrayOfObjects, propertyName, propertyValue);
if(searchingObject) {
preview.innerHTML = JSON.stringify(searchingObject, false, 2);
} else {
preview.innerHTML = "there is no object with property " + propertyName + " = " + propertyValue + " in your array of objects";
}
}
}
pre {
padding: 5px;
border-radius: 4px;
background: #f3f2f2;
}
textarea, button {
width: 100%
}
<fieldset>
<legend>Input Data:</legend>
<label>Put here your array of objects</label>
<textarea rows="7" id="arrayOfObjects">
[
{"a": 1, "b": 2},
{"a": 3, "b": 4},
{"a": 5, "b": 6},
{"a": 7, "b": 8, "c": 157}
]
</textarea>
<hr>
<label>property name: </label> <input type="text" id="propertyName" value="b"/>
<label>property value: </label> <input type="text" id="propertyValue" value=6 />
</fieldset>
<hr>
<button onclick="findObject()">find object in array!</button>
<hr>
<fieldset>
<legend>Searching Result:</legend>
<pre id="preview">click find</pre>
</fieldset>
var result = jsObjects.filter(x=> x.b === 6);
sera mieux, en utilisant le filtre de retour dans parfois vous ne pouvez pas obtenir de résultat
Utilisez find with bind pour transmettre des valeurs de clé spécifiques à une fonction de rappel.
function byValue(o) {
return o.a === this.a && o.b === this.b;
};
var result = jsObjects.find(byValue.bind({ a: 5, b: 6 }));