Чи можна отримати індекс, який ви сортуєте, в Underscore.js?


88

Я використовую бібліотеку JS Underscore і, зокрема, використовую виклики _.eachand і _.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){  });

Працює і для карти лодаша
Csaba Toth

6
На жаль, це фактично не працює в Lodash's 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 () підкреслення працює внутрішньо. _.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.