Можно ли получить индексируемый вами индекс в 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
});

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;
};

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


0

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.