从头创建下划线缩小功能

我正在创建自己的回调函数和更高阶的函数组。 我坚持复制下划线reduce函数或._reduce函数。 有人能帮助我理解它是如何在发动机罩下工作几天,对我而言,我很难过。 这是我到目前为止。 请理解我没有使用下划线库,我试图复制它,以便进一步理解高阶函数。 谢谢。

var reduce = function(collection, iterator, accumulator) {

    var iterator = function(startPoint, combiner){
      for(var i = 0; i <combiner.length; i++){
        startPoint += combiner[i];
    }
    return iterator(accumulator, collection);
}

在这些回答的评论中,Underscore的reduceArray.prototype.reduce之间存在很多混淆。 两个注释:

  • 下划线的reduce允许一个空的收集和没有种子值。 在这种情况下,它不会抛出错误,而是返回undefined 。 naomik已经说服了我,这是不安全的。 例如_([]).reduce(function(a, b) { return a + b}); 应该抛出一个错误或返回一个空列表。
  • 下划线的reduce对象和数组的作用。
  • 现在,到我原来的帖子:


    我实际上做了同样的事情 - 从头开始​​实施Underscore的关键功能 - 而后来, reduce可能是最棘手的。 我认为reduce更容易与非功能性reduce打交道(这一点可以归功于naomik):

    function reduce(arr, func, seed) {
        var result = seed,
            len = arr.length,
            i = 0;
        for (; i < len; i++) {
            result = func(result, arr[i])
         }
         return result
     }
    

    Underscore的实现稍微复杂一点,它处理对象和数组,处理空集合和可选的种子值。 它也使用each而不是for循环,因为它的风格更具功能性。 这是我实现的Underscore的reduce

    var reduce = function(coll, func, seed) {
        // `isEmpty` (not shown) handles empty arrays, strings, and objects.
        // Underscore accepts an optional seed value and does not 
        // throw an error if given an empty collection and no seed.
        if (isEmpty(coll)) {
            return coll;
        }
        var noSeed = arguments.length < 3;
    
        // `each` (not shown) should treat arrays and objects
        // in the same way.
        each(coll, function(item, i) {
            if (noSeed) {
                // This condition passes at most once. If it passes,
                // this means the user did not provide a seed value.
                // Default to the first item in the list.
                noSeed = false;
                seed = item;
            } else {
                seed = func(seed, item, i);
            }
        });
    
        return seed;
    };
    

    一个简单的递归函数可以做到这一点

    // arr - some array of values
    // f   - the reducing function
    // acc - initial value for the accumulator
    function reduce(arr, f, acc) {
      if (arr.length === 0)
        return acc
      else
        return reduce(arr.slice(1), f, f(acc, arr[0]))
    }
    
    // --------------------------------------------------
       
    // example 1:
    // reduce an array of numbers using an adding function
    
    var ex1 = reduce([1,2,3], function(acc, x) { return acc + x }, 0)
    
    console.log(ex1)
    //=> 6
    
    // --------------------------------------------------
    
    // example 2:
    // reduce an array of pairs to a mapping object
    
    var ex2 = reduce([['a', 1], ['b', 2], ['c', 3]], function(acc, pair) {
      var key = pair[0]
      var value = pair[1]
      acc[key] = value
      return acc
    }, {})
    
    console.log(ex2)
    //=> { a: 1, b: 2, c: 3 }

    它是这样的:

    function reduce(array, combine, start) {
      for (var i = 0; i < array.length; i++)
        start = combine(start, array[i]);
      return start;
    }
    
    console.log(reduce([1, 2, 3, 4], function(a, b) {
      return a + b;
    }, 0));
    

    链接参考:http://eloquentjavascript.net/05_higher_order.html

    链接地址: http://www.djcxy.com/p/34967.html

    上一篇: Creating the underscore reduce function from scratch

    下一篇: Create spec for REST API in Enterprise Architect