2016-08-15 41 views
-3

我偶然發現了這個代碼,是爲了重新定義Array.prototype.reduce:使用第一和最後的映射來實現減少

function first(array, n){ 
 
    return n === undefined ? array[0] : array.slice(0, n); 
 
}; 
 

 
function last(array, n){ 
 
    if(n> array.length){ 
 
    return array; 
 
    }else{ 
 
     return n === undefined ? array[array.legnth -1] : array.slice(array.length - n, array.length); 
 
     
 
}; 
 
    
 
    function map(collection, iterator){ 
 
    var arr = []; 
 
    each(collection, function(element, index){ 
 
     arr.push(iterator(element, index); 
 
    }); 
 
    return arr; 
 
    };

function reduce(collection, rf, acc) { 
    acc = acc === undefined ? first(collection) : acc; 
    return last(map(collection, function (value) { 
     acc = rf(acc, value); 
     return acc; 
    })); 
} 

不過,我不瞭解array.last()在這裏做什麼。有人可以請解釋。謝謝。

+1

數組沒有本地'last'函數。除非它也是數組原型的擴展。基於您的代碼,有沒有'array.last()'調用,所有我能看到的是一個'last'功能。在JavaScript範圍本身中實現了最後一步。你可以找到你自己的。 – choz

+0

'last'定義在哪裏 –

+0

您必須向我們展示'first()','last()'和'map()'函數,因爲這些函數不是標準的Javascript。我們可以猜測他們做了什麼,但如果我們不必猜測,這裏的答案會更好。另外,你問了'array.last()',但是在你的代碼中沒有這樣的東西。請花一些時間編寫/編輯一個明確的問題,其中包含所有必要的信息,以瞭解您所問的以及您的情況。現在,這個問題將被視爲「不清楚你要問什麼」,因爲它沒有足夠的信息。 – jfriend00

回答

0
0: function reduce(collection, rf, acc) { 
1:  acc = acc === undefined ? first(collection) : acc; 
2:  return last(map(collection, function (value) { 
3:   acc = rf(acc, value); 
4:   return acc; 
5:  })); 
6: } 

下面是發生了什麼事情在你的reduce()功能的逐行:

線路1:如果沒有值傳遞爲acc,將其設置爲集合中的第一個值。

第2行:致電map()您的集合將迭代集合,調用回調函數,對集合中的每個項目調用rf()map()創建一個新的數組,它是從每一次迭代回調被調用的返回值的集合。在結果陣列從map()返回,從那個數組last()價值和回報是從reduce()最終返回結果。

3號線:設置acc是的rf(acc, value)結果。

線4:從中map()將放入數組回調返回acc

但是,我不明白array.last()在這裏做什麼。可以 有人請解釋一下。

假設你的意思是last(array),你的last(array)的功能是獲取數組中的最後一項。如果傳遞第二個參數給last(),那麼它會從你在傳遞數組最後N項和返回,作爲一個新的數組(不使用本次能力)。


reduce()的實現似乎並不像它應該使用map()因爲有在創建這個內部數組是沒有意義的。我認爲這會更有效:

function reduce(collection, rf, initial) { 
    var acc = (initial === undefined) ? first(collection) : initial; 
    each(collection, function(value) { 
     acc = rf(acc, value); 
    }); 
    return acc; 
} 

如果要更精確地模仿Array.prototype.reduce()其中如果沒有選擇初始值,則陣列中的第一個元件被用作初始值和迭代器不是爲數組中的第一個元素調用的,那麼你可以這樣做:

function reduce(collection, rf, initial) { 
    var acc = initial, index = 0; 
    if (initial === undefined) { 
     acc = collection[0]; 
     index = 1; 
    } 
    for (; index < collection.length; ++index) { 
     acc = rf(acc, collection[index]); 
    }); 
    return acc; 
} 
+0

非常感謝您花時間解釋它。我同意。當你已經有回調時,這裏使用map似乎是多餘的,不必要的。使用每個似乎是理想的解決方法。 –

+0

快速問題 - 如果你迭代整個集合不會收集[0]。迭代兩次? –

+0

@IvonneTerrero - 是的,會的。這不是Javascript的'Array.prototype.reduce()'的行爲,但是你沒有提供所需行爲的規範,所以我沒有改變它的方面。 – jfriend00