降低功能中的变异累加器是否被视为不良做法? [英] Is mutating accumulator in reduce function considered bad practice?

查看:55
本文介绍了降低功能中的变异累加器是否被视为不良做法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是函数式编程的新手,我正在尝试重写一些代码,以使其更实用,从而掌握概念.刚才我发现了 Array.reduce()函数,并使用它创建了一个组合数组的对象(在此之前,我已经使用过 for 循环).但是,我不确定.看这段代码:

  const sortedCombinations = groups.reduce((总计,梳子)=>{if(accum [comb.strength]){accum [comb.strength] .push(comb);} 别的 {accum [comb.strength] = [comb];}归还},{}); 

很明显,此函数会更改其参数 accum ,因此不认为它是纯函数.另一方面,reduce函数(如果我正确理解的话)会在每次迭代中丢弃累加器,并且在调用回调函数后不使用累加器.不过,这不是一个纯粹的功能.我可以这样重写它:

  const sortedCombinations = groups.reduce((总计,梳子)=>{const tempAccum = Object.assign({},accum);if(tempAccum [comb.strength]){tempAccum [comb.strength] .push(comb);} 别的 {tempAccum [comb.strength] = [comb];}返回tempAccum;},{}); 

现在,据我所知,此功能被认为是纯函数.但是,它每次迭代都会创建一个新对象,这会花费一些时间,并且显然会占用内存.

所以问题是:哪个变种更好,为什么?纯度真的如此重要,以至于我应该牺牲性能和记忆力来实现它吗?还是我想念一些东西,还有更好的选择吗?

解决方案

尽管有任何潜在的性能问题(可能存在也可能不存在),但每次迭代都创建一个新对象是常见的做法,有时还是建议这样做.

关于性能是否以及如何成为问题,有很多讨论.但是请注意,访问对象和修改属性也不完全是免费"的.

您可以使函数纯例如通过这种方式:

  const sortedCombinations = groups.reduce((总计,梳子)=>{返回 {...累计[comb.strength]:[...(accum [comb.strength] || []),梳子]};},{}); 

如果您的状态和化简器在其他位置定义,则纯度可能变得更为重要

  const myReducer =(累加,梳状)=>{返回 {...累计[comb.strength]:[...(accum [comb.strength] || []),梳子]};};const initialState = {};const sortedCombinations = groups.reduce(myReducer,initialState);const otherSortedCombinations = otherCombinations.reduce(myReducer,initialState);const otherThing = otherList.reduce(otherReducer,initialState); 

I'm new to functional programming and I'm trying rewrite some code to make it more functional-ish to grasp the concepts. Just now I've discovered Array.reduce() function and used it to create an object of arrays of combinations (I've used for loop before that). However, I'm not sure about something. Look at this code:

const sortedCombinations = combinations.reduce(
    (accum, comb) => {
        if(accum[comb.strength]) {
            accum[comb.strength].push(comb);
        } else {
            accum[comb.strength] = [comb];
        }

        return accum;
    },
    {}
);

Obviously, this function mutates its argument accum, so it is not considered pure. On the other hand, the reduce function, if I understand it correctly, discards accumulator from every iteration and doesn't use it after calling callback function. Still, it's not a pure function. I can rewrite it like this:

const sortedCombinations = combinations.reduce(
    (accum, comb) => {
        const tempAccum = Object.assign({}, accum);
        if(tempAccum[comb.strength]) {
            tempAccum[comb.strength].push(comb);
        } else {
            tempAccum[comb.strength] = [comb];
        }

        return tempAccum;
    },
    {}
);

Now, in my understanding, this function is considered pure. However, it creates a new object every iteration, which consumes some time, and, obviously, memory.

So the question is: which variant is better and why? Is purity really so important that I should sacrifice performance and memory to achieve it? Or maybe I'm missing something, and there is some better option?

解决方案

Creating a new object on every iteration is common practice, and sometimes recommended, despite any potential performance issues (which may or may not exist).

There are a lot of discussions around about if and how performance is an issue. But note that accessing an object and modifying a property also doesn't come totally "for free".

You can make your function pure in e.g. in this way:

const sortedCombinations = combinations.reduce(
    (accum, comb) => {
        return {
            ...accum,
            [comb.strength]: [
                ...(accum[comb.strength] || []),
                comb
            ]
        };
    },
    {}
);

Purity might become more important if your state and reducer is defined somewhere else:

const myReducer = (accum, comb) => {
    return {
        ...accum,
        [comb.strength]: [
            ...(accum[comb.strength] || []),
            comb
        ]
    };
};

const initialState = {};
const sortedCombinations = combinations.reduce( myReducer, initialState );
const otherSortedCombinations = otherCombinations.reduce( myReducer, initialState );
const otherThing = otherList.reduce( otherReducer, initialState );

这篇关于降低功能中的变异累加器是否被视为不良做法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆