【问题标题】:Javascript Reduce from a compose function来自 compose 函数的 Javascript Reduce
【发布时间】:2023-03-08 03:45:01
【问题描述】:

我在试图向自己解释的在线课程中遇到一个问题。我理解“compose”函数/想法以更简单的格式做什么,但是当涉及到为函数工厂应用 reduce 并在每个函数上运行 compose 时,我似乎感到困惑。希望有经验的人可以更清楚地向我解释“return fns.reduce(compose)”行是怎么回事,以及它是如何一次实现这些功能的?一旦在底部调用函数,每个函数是否轮流成为“累加器”,然后是 reduce 中的“当前”?

const user = {
    user: 'Jennnifer',
    active: true,
    cart: [],
    purchases: []
}


const compose = (f, g) => (...args) => f(g(...args));

function purchaseItem(...fns){
    return fns.reduce(compose)
    // return Object.assign({}, user, {purchases: item})
}

//Receives a user, and the item
function addItemToCart(user, item){
    //Create a variable and concat the empty cart of the user object to add the item to the cart key.
    const updateCart = user.cart.concat(item);
    return Object.assign({}, user, { cart: updateCart });
}

function applyTaxToItems(user){
    const { cart } = user;
    const taxRate = 1.3;
    const updatedCart = cart.map(item => {
        return {
            name: item.name,
            price: item.price * taxRate
        }
    })

    return Object.assign({}, user, { cart: updatedCart})
}

function buyItem(user){
    return user
}

function emptyCart(user){
    return user
}

//Invoke Function:

console.log(purchaseItem
    (
        emptyCart,
        buyItem,
        applyTaxToItems,
        addItemToCart
    )(user, { name: 'Laptop', price: 200})
)

【问题讨论】:

    标签: javascript ecmascript-6 reduce


    【解决方案1】:

    你的函数名有点不对

    基本上您的 compose 函数仅用于 2 个函数

    你的purchaseItem 函数实际上没有购买任何东西。如果你仔细看,你会发现它只是返回 N 个函数的组合

    基本上,在reduce 的每个步骤中,您都将current 函数与accumulator 组合在一起——所有组合函数都来自之前的函数

    如果是第 0 步(没有before),那么它将组合前两个函数并将其放入accumulator

    最好重命名:

    compose -> compose2

    purchaseItem -> compose

    然后在你做的最后一个 console.log() 中

    purchaseItem
        (
            emptyCart,
            buyItem,
            applyTaxToItems,
            addItemToCart
        )(user, { name: 'Laptop', price: 200})
    

    为了更好地理解,你可以这样写

    // composition of 2 functions
    const compose2 = (f, g) => (...args) => f(g(...args))
    
    // composition of N functions
    const compose(...fns) => fns.reduce(compose2)
    
    // applying composition to 4 functions
    const purchaseItem = compose(
            emptyCart,
            buyItem,
            applyTaxToItems,
            addItemToCart
    )
    
    // calling 
    purchaseItem(user, { name: 'Laptop', price: 200})
    
    

    【讨论】:

    • 有趣.. 我想知道为什么参数“f”是 emptyCart 函数,而“g”代表其他函数的其余部分?我从 compose 控制台记录了 f 和 g 并在我的编辑器中看到了它。很神秘。
    【解决方案2】:

    上面的答案已经足够好了,但是对于reduce函数的reduce方法的更多逻辑理解。

    // reduce return : (...args) => prev(curr(...args));
    // f'     : (...args) => f(g(...args));
    // f''    : (...args) => f'(h(...args));    (...args) => f(g(h(...args))) 
    // f'''   : (...args) => f''(j(...args));   (...args) => f(g(h(j(...args)))) 
    // f''''  : (...args) => f'''(k(...args));  (...args) => f(g(h(j(k(...args)))))
    
    function compose(f, g) {
      return function(...args) {
        return f(g(...args))
      }
    }
    
    function composeAll(...fns) {
      return fns.reduce(compose) // return function is (...args) => f(g(h(j(k(...args)))))
    }
    
    function f(x) {return x+'1'}
    function g(x) {return x+'2'}
    function h(x) {return x+'3'}
    function j(x) {return x+'4'}
    function k(x) {return x+'5'}
    
    let result = composeAll(k, j, h, g, f)('cho');
    console.log(result); // cho12345
    

    前五行注释解释了reduce 函数的composeAll 返回值会发生什么。

    f'' : (...args) => f'(h(...args)); (...args) => f(g(h(...args)))

    表示(...args) => f'(h(...args))(...args) => f(g(h(...args)))相同

    我将这些表示为f'

    您需要区分reduce回调函数,reduce回调函数中的f, g(第9行)与composeAllfg参数的值不同(第14行)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-12-16
      • 2016-04-04
      • 1970-01-01
      • 2020-05-10
      • 1970-01-01
      • 2020-06-23
      • 2011-12-07
      • 1970-01-01
      相关资源
      最近更新 更多