9 votes

IndexOf élément dans un tableau js en utilisant une fonction de vérité en utilisant underscore ou jquery

J'ai besoin de la même fonctionnalité que celle d'Underscore. trouver mais avec l'index de l'élément comme résultat (et non l'élément lui-même).

Pour autant que je sache, Underscore's indexOf recherche une valeur et ne prend pas de fonction. Même problème pour la fonction jQuery inArray fonction.

J'ai trouvé l'implémentation suivante, mais je ne suis pas sûr qu'elle soit la plus efficace :

function myIndexOf(arr, filter) {
  var index;
  $.each(arr, function (i, elt) { if (filter(elt)) { index=i; return false; } });
  return index;
}

10voto

Paolo Moretti Points 9519

_.findIndex est disponible en Lo-Dash y Underscore.js :

var characters = [
  { 'name': 'barney',  'age': 36, 'blocked': false },
  { 'name': 'fred',    'age': 40, 'blocked': true },
  { 'name': 'pebbles', 'age': 1,  'blocked': false }
];

_.findIndex(characters, function(chr) {
  return chr.age < 20;
});
// → 2

_.findIndex(characters, { 'age': 36 });
// → 0

_.findIndex(characters, { 'name': 'dino' });
// → -1 (not found)

5voto

Luc125 Points 3144

Voici une mise en œuvre simple :

function find(collection, filter) {
    for (var i = 0; i < collection.length; i++) {
        if(filter(collection[i], i, collection)) return i;
    }
    return -1;
}

Il fonctionnera sur cualquier qui a une propriété de longueur, et vous pouvez passer une fonction de filtre complexe de la forme filter(element, index, collection) (paramètres facultatifs).

5voto

Brian Nickel Points 8687

Underscore utilise l'implémentation suivante :

_.find = function(obj, iterator, context) {
    var result;
    _.any(obj, function(value, index, list) {
        if(iterator.call(context, value, index, list)) {
            result = value;
            return true;
        }
    });
    return result;
}

Cela appelle à son tour, _.any qui appelle _.each qui appelle Array.prototype.forEach . L'efficacité n'est pas exactement le nom du jeu. Il s'agit plutôt d'utilité.

Si vous savez avec certitude que vous avez affaire à un tableau ou à un objet de type tableau, vous pouvez utiliser la solution de @Thor84no et simplement parcourir le tableau en boucle jusqu'à ce que votre condition de filtrage soit remplie. Si ce n'est pas le cas, et qu'il se peut que vous ayez affaire à des objets également, je réécrirais simplement _.find en _.findIndex et j'utiliserais result = index; .

3voto

Joel Points 129

Vous pouvez simplement utiliser une variable locale pour l'obtenir comme ceci :

var idx = 0; 
var match = _.detect(my_list, function(itm){
    return itm.something == some_test_value || ++idx == my_list.length && (idx = -1);
}

Viola. Vous avez l'index ET la valeur correspondante. Si l'itérateur atteint la fin, l'index passe à -1, et si vous trouvez une correspondance, il court-circuite sur cet index.

2voto

Thor84no Points 2969

Il serait plus efficace de faire la boucle for vous-même et d'utiliser break; (ou return ) pour quitter la boucle une fois que vous avez trouvé l'index.

for (var i = 0; i < arr.length; i++) {
    if (filter(arr[i])) {
        return i;
    }
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X