【问题标题】:How to make a function as pure function using javascript and react?如何使用javascript将函数设为纯函数并做出反应?
【发布时间】:2022-01-12 09:23:31
【问题描述】:

我有如下数据,

const arr_obj = [
    {
        id: '1',
        children: [],
        type: 'TYPE1',
    },
    {
        id: '2',
        children: [
            {
                id: '1',
                children: [
                    {
                        //some attributes
                    }
                ],
                type: 'MAIN',
            },
            {
                id: '2',
                children: [
                    {
                        //some attributes
                     }
                ],
                type: 'MAIN',
            },
            {
                id: '3',
                children: [
                    {
                        //some attributes
                    }
                ],
                type: 'MAIN',
            },
        ]
        type: 'TYPE2',
    },
    {
        id: '3',
        children: [
            {
                id: '4',
                children: [
                    {
                        //some attributes
                    }
                ],
                type: 'MAIN',
            },
            {
                id: '5',
                children: [
                    {
                        //some attributes
                    }
                ],
                type: 'MAIN',
            },
            {
                id: '6',
                children: [
                    {
                        //some attributes
                    }
                ],
                type: 'MAIN',
            },
        ]
        type: 'TYPE2',
    }
]

我必须找出类型的计数:'MAIN'。这些“主要”将在类型内:“type2”

所以预期的计数是 6。

下面是代码,

const ParentComponent = () => {
    const findCount = (arr_obj) => {
        let count = 0;
        const expectedCount = 2;
        const loop = (children) => {
            for (const obj of children) {
                const { type, children } = obj;
                if (type === 'TYPE2') {
                    loop(children);
                } else if (type === 'MAIN') {
                    ++count;
                    if (count > expectedCount) return;
                }
            }
        };
        loop(children);
        return count > expectedCount;
    };

    const output = findCount(arr_obj);

    return (
        //some jsx rendering
    );
 }

上面的代码工作正常。但我想让循环(子)函数成为一个纯函数。我不知道该怎么做。

现在的问题是我在循环方法之外定义变量。 如何将所有内容定义为函数的参数,您可以将函数移到组件之外。

有人可以帮我解决这个问题吗?谢谢。

【问题讨论】:

  • “纯”函数是什么意思?
  • 你有更多的嵌套级别吗?
  • @Ricky Mo:没有外部依赖。
  • @Nina Scholz:是的,它可以有。但主要是所需的类型在子数组中
  • @RickyMo:所以就像目前我在组件中定义了变量一样。我怎样才能把函数循环和其他需要的变量放在组件之外,使它成为一个纯函数,不处理外部的任何状态

标签: javascript reactjs


【解决方案1】:

您可以获取所需类型顺序的数组并仅迭代一个级别并移交其余所需类型。如果没有剩余类型,则返回一个,否则返回嵌套计数的结果。

const
    getCount = (array, types) => {
        let count = 0;
        for (const { type, children } of array) {
            if (types[0] === type) {
                count += types.length === 1
                    ? 1
                    : getCount(children, types.slice(1));
            }
        }
        return count;
    }
    data = [{ id: '1', children: [], type: 'TYPE1' }, { id: '2', children: [{ id: '1', children: [{}], type: 'MAIN' }, { id: '2', children: [{}], type: 'MAIN' }, { id: '3', children: [{} ], type: 'MAIN' }], type: 'TYPE2' }, { id: '3', children: [{ id: '4', children: [{}], type: 'MAIN' }, { id: '5', children: [{}], type: 'MAIN' }, { id: '6', children: [{}], type: 'MAIN' }], type: 'TYPE2' }],
    order = ['TYPE2', 'MAIN'],
    count = getCount(data, order);

console.log(count);

【讨论】:

  • 谢谢。你能解释一下这条线的作用吗?计数 += types.length === 1 ? 1 : getCount(children, types.slice(1));
  • 它根据types 的长度添加一个或嵌套调用的计数。如果是 1,则该函数已访问所有以前需要的类型,并且位于所需嵌套结构的末尾。
【解决方案2】:

纯函数是一个函数(代码块),如果传递相同的参数,它总是返回相同的结果。它不依赖于任何状态,也不依赖于程序执行期间的数据变化,而只依赖于其输入参数。

Reference

在上面的共享代码中,我可以看到 expectedCount 作为共享变量,它不是 PURE 函数。

我可以看到您的 cmets 所需的类型是儿童,然后它只是 2 个级别。那么下面的代码就可以工作了。

function count(data, condition) {
    let count = 0;
    data.forEach((value, index) => {
    if(value.type === condition[0]){
        value.children.forEach((val, idx) => {
            if(val.type === condition[1]) {
            count++;
          }
        })
      }
    });
    return count;
}
const condition = ['TYPE2', 'MAIN'];
console.log(count(arr_obj, condition));

【讨论】:

    【解决方案3】:

    Nina 的回答更中肯,但您也可以通过过滤输入数组来做到这一点。

    const data = [{ id: '1', children: [], type: 'TYPE1' }, { id: '2', children: [{ id: '1', children: [{}], type: 'MAIN' }, { id: '2', children: [{}], type: 'MAIN' }, { id: '3', children: [{} ], type: 'MAIN' }], type: 'TYPE2' }, { id: '3', children: [{ id: '4', children: [{}], type: 'MAIN' }, { id: '5', children: [{}], type: 'MAIN' }, { id: '6', children: [{}], type: 'MAIN' }], type: 'TYPE2' }];
    
    const count = data
      .filter(v=>v.type==='TYPE2')
      .flatMap(v=>v.children)
      .filter(v=>v.type==='MAIN')
      .length
    
    console.log(count);

    【讨论】:

      猜你喜欢
      • 2016-12-23
      • 2021-11-17
      • 2017-10-16
      • 2021-05-08
      • 1970-01-01
      • 2020-06-07
      • 2019-05-09
      • 1970-01-01
      • 2018-08-20
      相关资源
      最近更新 更多