web-dev-qa-db-ja.com

Underscore.jsでソートしているインデックスを取得することは可能ですか?

私は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); 
});
87
contactmatt

インデックスは実際に利用可能です;

_.sortBy([1, 4, 2, 66, 444, 9], function(num, index){  });
159
osoner

イテレーターfunctionに別のパラメーターを追加することにより、現在の反復のインデックスを取得できます。

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

配列を変換する場合は、アンダースコアのiterator関数のmapパラメーターにも2番目の引数としてインデックスが渡されます。そう:

_.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"]
19
Martin Dow

_.eachの反復子は、3つのパラメーター(element, index, list)で呼び出されます。はい、_.eachの場合、インデックスを取得できます。

SortByでも同じことができます

9
janith

Underscoreの_.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

参考のため、これはUnderscore.js 1.8.3の_.each()コードです

_.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;
};
5
mszymulanski

より一般的には、ほとんどの状況で、最初の2つの引数としてリストと引数を取るアンダースコア関数は、イテレーターの最後から2番目の引数としてリストインデックスへのアクセスを提供します。これは、3番目の引数として「メモ」を取る2つのアンダースコア関数_.reduceおよび_.reduceRightに関して重要な違いです。これら2つの場合、インデックスは2番目の引数ではありませんが、三番:

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

1
George Jempty

利用可能な場合、ほとんどのlodash配列関数は反復を示すと信じています。しかし、ソートは実際には同じ方法での反復ではありません。66番の場合、完了するまで配列の4番目の項目を処理しません。カスタムの並べ替え関数は、すべてが適切な場所に配置されるまで、隣接する数値を前後にずらして、配列を何度もループします。

0
Sir_Mapsalot