Je me demande s'il existe une méthode connue, intégrée / élégante pour trouver le premier élément d'un tableau JS correspondant à une condition donnée. L'équivalent AC # serait List.Find .
Jusqu'à présent, j'utilise un combo à deux fonctions comme celui-ci:
// Returns the first element of an array that satisfies given predicate
Array.prototype.findFirst = function (predicateCallback) {
if (typeof predicateCallback !== 'function') {
return undefined;
}
for (var i = 0; i < arr.length; i++) {
if (i in this && predicateCallback(this[i])) return this[i];
}
return undefined;
};
// Check if element is not undefined && not null
isNotNullNorUndefined = function (o) {
return (typeof (o) !== 'undefined' && o !== null);
};
Et puis je peux utiliser:
var result = someArray.findFirst(isNotNullNorUndefined);
Mais comme il y a tellement de méthodes de tableau de style fonctionnel dans ECMAScript , peut-être qu'il y a déjà quelque chose comme ça? J'imagine que beaucoup de gens doivent implémenter des trucs comme ça tout le temps ...
javascript
arrays
Jakub P.
la source
la source
return (typeof (o) !== 'undefined' && o !== null);
jusqu'à celareturn o != null;
. Ils sont exactement équivalents.Réponses:
Depuis ES6, il existe une
find
méthode native pour les tableaux; cela arrête l'énumération du tableau une fois qu'il trouve la première correspondance et renvoie la valeur.Ancienne réponse:
Je dois poster une réponse pour arrêter ces
filter
suggestions :-)Vous pouvez utiliser la
some
méthode Array pour itérer le tableau jusqu'à ce qu'une condition soit remplie (puis s'arrêter). Malheureusement, il ne retournera que si la condition a été remplie une fois, et non par quel élément (ou à quel indice) elle a été remplie. Nous devons donc l'amender un peu:la source
some()
d'autre part, retourne immédiatement, ce qui est beaucoup plus rapide dans presque tous les cas que les solutions de filtrage.Depuis ECMAScript 6, vous pouvez l'utiliser
Array.prototype.find
pour cela. Ceci est implémenté et fonctionne dans Firefox (25.0), Chrome (45.0), Edge (12) et Safari (7.1), mais pas dans Internet Explorer ou un tas d'autres plates-formes anciennes ou peu communes .Par exemple, l'expression ci-dessous est évaluée à
106
.Si vous souhaitez l'utiliser maintenant mais avez besoin de la prise en charge d'IE ou d'autres navigateurs non compatibles, vous pouvez utiliser un shim. Je recommande l' es6-shim . MDN propose également une cale si, pour une raison quelconque, vous ne voulez pas mettre l'intégralité de la cale es6 dans votre projet. Pour une compatibilité maximale, vous voulez le shim es6, car contrairement à la version MDN, il détecte les implémentations natives boguées de
find
et les remplace (voir le commentaire qui commence "Contournement des bogues dans Array # find et Array # findIndex" et les lignes qui le suivent immédiatement) .la source
find
est mieux quefilter
puisquefind
s'arrête immédiatement lorsqu'il trouve un élément correspondant à la condition, tandis quefilter
boucle tous les éléments pour donner tous les éléments correspondants.Qu'en est-il de l'utilisation du filtre et de l'obtention du premier index du tableau résultant?
la source
.shift
ici?shift
est qu'il "semble intelligent" mais est en fait plus déroutant. Qui penserait qu'appelershift()
sans argument reviendrait à prendre le premier élément? Ce n'est pas clair OMI. L'accès à la baie.shift()
plus[0]
explicitement indiquée comme ceci. Malgré cela, c'est une alternative que vous pouvez choisir d'utiliser ou non, je resterais[0]
cependant.Il devrait être clair maintenant que JavaScript n'offre pas une telle solution de manière native; voici les deux dérivés les plus proches, les plus utiles en premier:
Array.prototype.some(fn)
offre le comportement souhaité d'arrêt lorsqu'une condition est remplie, mais renvoie uniquement si un élément est présent; il n'est pas difficile d'appliquer une ruse, comme la solution offerte par la réponse de Bergi .Array.prototype.filter(fn)[0]
en fait un super doublure mais est le moins efficace, car vous jetez desN - 1
éléments juste pour obtenir ce dont vous avez besoin.Les méthodes de recherche traditionnelles en JavaScript se caractérisent par le retour de l'index de l'élément trouvé au lieu de l'élément lui-même ou -1. Cela évite d'avoir à choisir une valeur de retour dans le domaine de tous les types possibles; un index ne peut être qu'un nombre et les valeurs négatives ne sont pas valides.
Les deux solutions ci-dessus ne prennent pas en charge la recherche de décalage non plus, j'ai donc décidé d'écrire ceci:
la source
Résumé:
ES6
find()
find()
est situé surArray.prototype
afin qu'il puisse être utilisé sur chaque baie.find()
prend un rappel où uneboolean
condition est testée. La fonction renvoie la valeur (pas l'index!)Exemple:
la source
Si vous utilisez,
underscore.js
vous pouvez utiliser ses fonctionsfind
etindexOf
pour obtenir exactement ce que vous voulez:Documentation:
la source
Depuis ES 2015,
Array.prototype.find()
prévoit cette fonctionnalité exacte.Pour les navigateurs qui ne prennent pas en charge cette fonctionnalité, le Mozilla Developer Network a fourni un polyfill (collé ci-dessous):
la source
Array.prototype.find () fait exactement cela, plus d'informations: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find
la source
la source
Je me suis inspiré de plusieurs sources sur Internet pour trouver la solution ci-dessous. Voulait prendre en compte à la fois une valeur par défaut et fournir un moyen de comparer chaque entrée pour une approche générique que cela résout.
Utilisation: (donnant la valeur "Second")
La mise en oeuvre:
la source
Il n'y a pas de fonction intégrée en Javascript pour effectuer cette recherche.
Si vous utilisez jQuery, vous pouvez le faire
jQuery.inArray(element,array)
.la source
$.inArray
ne renvoie pas de booléen, il (étonnamment!) Renvoie l'index du premier élément correspondant. Cependant, il ne fait toujours pas ce que le PO a demandé.Une manière moins élégante qui contiendra
throw
tous les bons messages d'erreur (basés surArray.prototype.filter
) mais cessera d'itérer sur le premier résultat estEnsuite, des exemples sont
Cela fonctionne en terminant
filter
en utilisantthrow
.la source