递归函数在js中持久化结果

我有以下代码按顺序获取项目的所有名称,例如 name1、name2、name3、name31、name32 ... 等等,还根据某些条件将某些选择设置为 true 或 false。我正在尝试使用递归函数来解决它。但是我不知道如何持久化结果并在最后返回它们。


arr = [

    {

      name: 'name1',

      selected: true,

      children: [

        { name: 'name2', selected: false, children: [] },

        {

          name: 'name3',

          selected: false,

          children: [

            { name: 'name31', selected: false, children: [] },

            {

              name: 'name32',

              selected: false,

              children: [

                { name: 'name321', selected: false, children: [] },

                { name: 'name322', selected: false, children: [] },

                { name: 'name323', selected: false, children: [] },

              ],

            },

            { name: 'name33', selected: false, children: [] },

          ],

        },

        { name: 'name4', selected: false, children: [] },

      ],

    },

  ];


  myfunc(items) {

    const result = [];

    for (const item of items) {

      item.selected = false;

      myfunc(item.children);

      result.push(item.name);

    }

    return result;

  }


 const result = myfunc(arr);


慕桂英4014372
浏览 161回答 4
4回答

一只斗牛犬

你可以得到names使用Array.prototype.flatMap-const names = t =>  t.flatMap(v => [ v.name, ...names(v.children) ])names(arr)// ...["name1", "name2", "name3", "name31", "name32", "name321", "name322", "name323", "name33", "name4"]

狐的传说

我强烈建议对于您尝试做的两件事,即查找名称列表和更改某些值select,您可以在两个单独的函数中进行。您总是可以编写一个包装函数来完成这两项工作,但是这两者有不相关的要求;将它们结合起来会增加不必要的复杂性。这里已经有一个很好的名称解决方案。看到Thankyou的回答。对于其他要求,我建议您分成三个不同的部分。“根据某些条件将某些选择设置为 true 或 false”是两部分:一个用于测试您的条件,另一个用于进行更改。第三部分是执行数据实际遍历的代码。(此外,可能还有第四个;我在下面的示例假设您仅在条件为真时才对数据执行某些操作,但您可以运行两种不同的操作:一个为真,另一个为假。)你实际上没有描述你的情况,所以我会补一个。我要说的是,如果末尾的数字name为奇数,则条件为真。我们需要一个函数来返回设置为 true 的对象版本selected。这里有两个简单的辅助函数:const nameIsOdd = ({name}) =>  Number (name .replace (/\D/g, '')) % 2 === 1const selectedTrue = ({select, ...rest}) =>  ({...rest, selected: true})(请注意,我说我们返回一个具有更新属性的对象。我更喜欢使用不可变的数据,并返回我的结构的更改版本,而不是对结构进行更改。)现在我们可以编写一个函数来递归遍历一组具有children属性的对象,接受一个谓词函数和一个来创建更新的节点。其实很简单:const alterNodes = (pred, change) => (xs) =>  xs .map (({children = [], ...rest}) => ({    ... (pred (rest) ? change (rest) : rest),    children: alterNodes (pred, change) (children)  }))使用它,我们现在非常简单地编写我们的主要功能:const fixSelected = alterNodes (nameIsOdd, selectedTrue)您可以在以下代码片段中看到这一点:const alterNodes = (pred, change) => (xs) =>  xs .map (({children = [], ...rest}) => ({    ... (pred (rest) ? change (rest) : rest),    children: alterNodes (pred, change) (children)  }))const nameIsOdd = ({name}) =>  Number (name .replace (/\D/g, '')) % 2 === 1const selectedTrue = ({select, ...rest}) =>  ({...rest, selected: true})const fixSelected = alterNodes (nameIsOdd, selectedTrue)const arr = [{name: 'name1', selected: true, children: [{name: 'name2', selected: false, children: []}, {name: 'name3', selected: false, children: [{name: 'name31', selected: false, children: []}, {name: 'name32', selected: false, children: [{name: 'name321', selected: false, children: []}, {name: 'name322', selected: false, children: []}, {name: 'name323', selected: false, children: []}]}, {name: 'name33', selected: false, children: []}]}, {name: 'name4', selected: false, children: []}]}];console .log (fixSelected (arr)).as-console-wrapper {max-height: 100% !important; top: 0}

犯罪嫌疑人X

const result = [];function myfunc(items) {    items.forEach((item)=>{        item.selected = false;        result.push(item.name);        myfunc(item.children)    })    return result; }将结果移到函数之外,否则每次调用都会声明它,并且它的值将被重置。

守着一只汪

您已经在递归调用中初始化了结果变量,它将仅返回初始值,所有迭代值都将被省略。这将工作,temp = [];function myfunc(items) {    for (item of items) {        temp.push(item.name);        if (typeof item.children !== 'undefined') {            myfunc(item.children);        }    }    return temp; //this is optional, use temp directly}const result = myfunc(arr);
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript