È possibile ottenere l'indice che stai ordinando in Underscore.js?


88

Sto utilizzando la libreria JS Underscore e in particolare le chiamate di libreria _.eache _.sortby. Mi chiedo se esiste un modo possibile per ottenere l'indice del valore all'interno del delegato iteratore

_.sortBy([1, 4, 2, 66, 444, 9], function(num){ 
    /*It'd be great to have access to the index in here */
    return Math.sin(num); 
});

Risposte:


163

L'indice è effettivamente disponibile come;

_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){  });

Funziona anche per la mappa di lodash
Csaba Toth

6
Purtroppo, questo in realtà non funziona in Lodash a sortBypartire dalla versione 4.17.4, che probabilmente è più utile sapere in questo scenario.
Jonathan Dumaine

81

Puoi ottenere l'indice dell'iterazione corrente aggiungendo un altro parametro al tuo iteratore function, ad es

_.each(['foo', 'bar', 'baz'], function (val, i) {
    console.log(i + ": " + val); // 0: foo, 1: bar, 2: baz
});

19

Se preferisci trasformare il tuo array, anche il iteratorparametro della mapfunzione di underscore viene passato all'indice come secondo argomento. Così:

_.map([1, 4, 2, 66, 444, 9], function(value, index){ return index + ':' + value; });

... ritorna:

["0:1", "1:4", "2:2", "3:66", "4:444", "5:9"]

10

L'iteratore di _.eachviene chiamato con 3 parametri (element, index, list). Quindi sì, per_.each te taxi ottieni l'indice.

Puoi fare lo stesso in sortBy


6

Penso che valga la pena menzionare come funziona internamente _.each () di Underscore. _.Each (list, iteratee) controlla se l'elenco passato è un oggetto array o un oggetto.

Nel caso in cui l'elenco sia un array, gli argomenti iterati saranno un elemento e un indice di elenco come nell'esempio seguente:

var a = ['I', 'like', 'pancakes', 'a', 'lot', '.'];
_.each( a, function(v, k) { console.log( k + " " + v); });

0 I
1 like
2 pancakes
3 a
4 lot
5 .

D'altra parte, se l'argomento della lista è un oggetto, l'iterazione prenderà un elemento della lista e una chiave:

var o = {name: 'mike', lastname: 'doe', age: 21};
_.each( o, function(v, k) { console.log( k + " " + v); });

name mike
lastname doe
age 21

Per riferimento questo è il codice _.each () da Underscore.js 1.8.3

_.each = _.forEach = function(obj, iteratee, context) {
   iteratee = optimizeCb(iteratee, context);
   var i, length;
   if (isArrayLike(obj)) {
      for (i = 0, length = obj.length; i < length; i++) {
         iteratee(obj[i], i, obj);
      }
   } else {
      var keys = _.keys(obj);
      for (i = 0, length = keys.length; i < length; i++) {
         iteratee(obj[keys[i]], keys[i], obj);
      }
   }
   return obj;
};

1

Più in generale, nella maggior parte dei casi, le funzioni di sottolineatura che accettano una lista e un argomento come primi due argomenti, forniscono l'accesso all'indice della lista come il penultimo argomento dell'iteratore. Questa è una distinzione importante quando si tratta delle due funzioni di sottolineatura, _.reduce e _.reduceRight, che prendono 'memo' come terzo argomento - nel caso di queste due l'indice non sarà il secondo argomento, ma il terzo:

var destination = (function() {
    var fields = ['_333st', 'offroad', 'fbi'];
    return _.reduce(waybillInfo.destination.split(','), function(destination, segment, index) {
        destination[fields[index]] = segment;
        return destination;
    }, {});
})();

console.log(destination);            
/*
_333st: "NYARFTW  TX"
fbi: "FTWUP"
offroad: "UP"

The following is better of course but not demonstrate my point:
var destination = _.object(['_333st', 'offroad', 'fbi'], waybillInfo.destination.split(','));
*/

Quindi, se si voleva si potrebbe ottenere l'indice utilizzando sottolineatura stesso: _.last(_.initial(arguments)). Una possibile eccezione (non ho provato) è _.map, in quanto può prendere un oggetto invece di una lista: "Se list è un oggetto JavaScript, gli argomenti dell'iteratore saranno (valore, chiave, lista)." - vedi: http://underscorejs.org/#map


0

Quando disponibile, credo che la maggior parte delle funzioni dell'array lodash mostrerà l'iterazione. Ma l'ordinamento non è davvero un'iterazione allo stesso modo: quando sei sul numero 66, non stai elaborando il quarto elemento nell'array finché non è finito. Una funzione di ordinamento personalizzata eseguirà un ciclo attraverso un array un certo numero di volte, spingendo i numeri adiacenti in avanti o indietro, finché tutto non sarà al suo posto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.