Можно ли получить индексируемый вами индекс в Underscore.js?

88

Я использую библиотеку JS Underscore и, в частности, использую вызовы библиотеки _.eachи _.sortby. Мне интересно, есть ли какой-либо способ получить индекс значения в делегате итератора

_.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); 
});
контакты
источник

Ответы:

163

Индекс действительно доступен как;

_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){  });
озонатор
источник
Работает также для карты lodash
Csaba Toth
6
К сожалению, на самом деле это не работает в Lodash sortByверсии 4.17.4, что, вероятно, более полезно знать в этом сценарии.
Джонатан
81

Вы можете получить индекс текущей итерации, добавив еще один параметр в свой итератор function, например

_.each(['foo', 'bar', 'baz'], function (val, i) {
    console.log(i + ": " + val); // 0: foo, 1: bar, 2: baz
});
jabclab
источник
19

Если вы предпочитаете преобразовать свой массив, то iteratorпараметру функции подчеркивания mapтакже передается индекс в качестве второго аргумента. Так:

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

... возвращает:

["0:1", "1:4", "2:2", "3:66", "4:444", "5:9"]
Мартин Доу
источник
10

Итератор _.eachвызывается с 3 параметрами (element, index, list). Так что да, _.eachвы получите индекс.

Вы можете сделать то же самое в sortBy

Джанит
источник
6

Я думаю, стоит упомянуть, как _.each () Underscore работает внутри. _.Each (list, iteratee) проверяет, является ли переданный список объектом массива или объектом.

В случае, если список является массивом, итерационные аргументы будут элементом списка и индексом, как в следующем примере:

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 .

С другой стороны, если аргумент списка является объектом, итератор примет элемент списка и ключ:

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

name mike
lastname doe
age 21

Для справки это код _.each () из 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
источник
1

В более общем смысле, в большинстве случаев функции подчеркивания, которые принимают список и аргумент в качестве первых двух аргументов, предоставляют доступ к индексу списка в качестве предпоследнего аргумента итератора. Это важное различие, когда речь идет о двух функциях подчеркивания, _.reduce и _.reduceRight, которые принимают 'memo' в качестве третьего аргумента - в случае этих двух индекс будет не вторым аргументом, а третий:

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

Так что если вы хотите , вы можете получить индекс , используя подчеркивание себя: _.last(_.initial(arguments)). Возможным исключением (я не пробовал) является _.map, так как он может принимать объект вместо списка: «Если список является объектом JavaScript, аргументами итератора будут (значение, ключ, список)». - см .: http://underscorejs.org/#map

Dexygen
источник
0

Я полагаю, что когда доступно, большинство функций массива lodash покажут итерацию. Но сортировка на самом деле не является итерацией в том же смысле: когда вы находитесь на числе 66, вы не обрабатываете четвертый элемент в массиве, пока он не завершится. Пользовательская функция сортировки будет перебирать массив несколько раз, сдвигая соседние числа вперед или назад, пока все не окажется на своих местах.

Sir_Mapsalot
источник