Ответ 1
Индекс действительно доступен, например:
_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){ });
Я использую библиотеку JS Underscore и, в частности, используя _.each
и _.sortby
. Мне интересно, есть ли какой-либо возможный способ получить индекс значения внутри делегата iterator
_.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);
});
Индекс действительно доступен, например:
_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){ });
Вы можете получить индекс текущей итерации, добавив еще один параметр в ваш итератор function
, например.
_.each(['foo', 'bar', 'baz'], function (val, i) {
console.log(i + ": " + val); // 0: foo, 1: bar, 2: baz
});
Если вы предпочтете преобразовать свой массив, тогда параметр 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"]
Итератор _.each
вызывается с тремя параметрами (element, index, list)
. Так что да, для _.each
вы получите калькулятор.
Вы можете сделать то же самое в sortBy
Я думаю, стоит упомянуть, как Underscore _.each() работает внутри. _.each(list, iteratee) проверяет, является ли переданный список объектом массива или объектом.
В случае, когда список является массивом, аргументы 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 .
С другой стороны, если аргумент list является объектом, iteratee примет элемент списка и ключ:
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;
};
В общем случае, в большинстве случаев, подчеркивание функций, которые принимают список и аргумент в качестве первых двух аргументов, предоставляют доступ к индексу списка в качестве последнего аргумента для итератора. Это важное различие, когда речь идет о двух элементах подчеркивания: _.reduce и _.reduceRight, которые принимают "памятку" в качестве третьего аргумента - в случае этих двух индекс не будет вторым аргументом, но третье:
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