Saya menggunakan perpustakaan JS Underscore dan khususnya menggunakan panggilan perpustakaan _.each
dan _.sortby
. Saya bertanya-tanya apakah ada cara yang mungkin untuk mendapatkan indeks nilai dalam delegasi 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);
});
javascript
underscore.js
contactmatt
sumber
sumber
sortBy
sejak versi 4.17.4, yang mungkin lebih membantu untuk diketahui dalam skenario ini.Anda bisa mendapatkan indeks dari iterasi saat ini dengan menambahkan parameter lain ke iterator Anda
function
, misalnya_.each(['foo', 'bar', 'baz'], function (val, i) { console.log(i + ": " + val); // 0: foo, 1: bar, 2: baz });
sumber
Jika Anda lebih suka mengubah array Anda, maka
iterator
parametermap
fungsi garis bawah juga diteruskan indeks sebagai argumen kedua. Begitu:_.map([1, 4, 2, 66, 444, 9], function(value, index){ return index + ':' + value; });
... kembali:
["0:1", "1:4", "2:2", "3:66", "4:444", "5:9"]
sumber
Iterator
_.each
disebut dengan 3 parameter(element, index, list)
. Jadi ya, bagi_.each
Anda taksi mendapatkan indeks.Anda dapat melakukan hal yang sama di sortBy
sumber
Saya pikir perlu disebutkan bagaimana Underscore _.each () bekerja secara internal. _.Each (list, iteratee) memeriksa apakah daftar yang dilewati adalah objek array, atau objek.
Jika listnya adalah array, argumen iteratee akan menjadi elemen list dan indeks seperti pada contoh berikut:
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 .
Di sisi lain, jika argumen list adalah sebuah objek, iteratee akan mengambil elemen list dan sebuah key:
var o = {name: 'mike', lastname: 'doe', age: 21}; _.each( o, function(v, k) { console.log( k + " " + v); }); name mike lastname doe age 21
Untuk referensi ini adalah kode _.each () dari 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; };
sumber
Secara lebih umum, dalam kebanyakan keadaan, fungsi garis bawah yang mengambil daftar dan argumen sebagai dua argumen pertama, memberikan akses ke indeks daftar sebagai argumen di samping terakhir ke iterator. Ini adalah perbedaan penting dalam hal dua fungsi garis bawah, _.reduce dan _.reduceRight, yang menganggap 'memo' sebagai argumen ketiga mereka - dalam kasus dua ini indeks tidak akan menjadi argumen kedua, tetapi ketiga:
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(',')); */
Jadi jika Anda ingin Anda bisa mendapatkan indeks menggunakan garis bawah itu sendiri:
_.last(_.initial(arguments))
. Pengecualian yang mungkin (saya belum mencoba) adalah _.map, karena dapat mengambil objek alih-alih daftar: "Jika daftar adalah objek JavaScript, argumen iterator akan menjadi (nilai, kunci, daftar)." - lihat: http://underscorejs.org/#mapsumber
Jika tersedia, saya yakin sebagian besar fungsi lodash array akan menampilkan iterasi. Tetapi pengurutan sebenarnya bukan pengulangan dengan cara yang sama: saat Anda berada di nomor 66, Anda tidak memproses item keempat dalam larik sampai selesai. Fungsi pengurutan kustom akan mengulang melalui array beberapa kali, mendorong nomor yang berdekatan maju atau mundur, hingga semuanya berada di tempat yang tepat.
sumber