¿Es posible obtener el índice que está ordenando en Underscore.js?

88

Estoy usando la biblioteca de JS subrayado y en particular el uso de los _.eachy _.sortbylas bibliotecas llamadas. Me pregunto si hay alguna forma posible de obtener el índice del valor dentro del delegado del iterador

_.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); 
});
contactmatt
fuente

Respuestas:

163

El índice está realmente disponible como;

_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){  });
osoner
fuente
También funciona para el mapa de Lodash
Csaba Toth
6
Lamentablemente, esto en realidad no funciona en Lodash a sortBypartir de la versión 4.17.4, lo que probablemente sea más útil saber en este escenario.
Jonathan Dumaine
81

Puede obtener el índice de la iteración actual agregando otro parámetro a su iterador function, por ejemplo

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

Si prefiere transformar su matriz, entonces el iteratorparámetro de la mapfunción de subrayado también se pasa al índice como segundo argumento. Entonces:

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

... devoluciones:

["0:1", "1:4", "2:2", "3:66", "4:444", "5:9"]
Martin Dow
fuente
10

El iterador de _.eachse llama con 3 parámetros (element, index, list). Así que sí, para _.eachtu taxi obtén el índice.

Puedes hacer lo mismo en sortBy

Janith
fuente
6

Creo que vale la pena mencionar cómo funciona internamente _.each () del subrayado. _.Each (list, iteratee) comprueba si la lista pasada es un objeto de matriz o un objeto.

En el caso de que la lista sea una matriz, los argumentos iterados serán un elemento de lista y un índice como en el siguiente ejemplo:

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 .

Por otro lado, si el argumento de la lista es un objeto, el iteratee tomará un elemento de lista y una clave:

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

name mike
lastname doe
age 21

Como referencia, este es el código _.each () de 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;
};
mszymulanski
fuente
1

De manera más general, en la mayoría de las circunstancias, las funciones de subrayado que toman una lista y un argumento como los dos primeros argumentos proporcionan acceso al índice de la lista como el penúltimo argumento del iterador. Esta es una distinción importante cuando se trata de las dos funciones de subrayado, _.reduce y _.reduceRight, que toman 'memo' como su tercer argumento; en el caso de estos dos, el índice no será el segundo argumento, sino el tercero:

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(','));
*/

Así que si quería que podría obtener el índice mediante subrayado en sí: _.last(_.initial(arguments)). Una posible excepción (no lo he intentado) es _.map, ya que puede tomar un objeto en lugar de una lista: "Si la lista es un objeto JavaScript, los argumentos del iterador serán (valor, clave, lista)". - ver: http://underscorejs.org/#map

Dexygen
fuente
0

Cuando esté disponible, creo que la mayoría de las funciones de matriz lodash mostrarán la iteración. Pero ordenar no es realmente una iteración de la misma manera: cuando estás en el número 66, no estás procesando el cuarto elemento de la matriz hasta que esté terminado. Una función de clasificación personalizada recorrerá una matriz varias veces, empujando los números adyacentes hacia adelante o hacia atrás, hasta que todo esté en su lugar correcto.

Sir_Mapsalot
fuente