Javascript js中的递归函数persist结果

Javascript js中的递归函数persist结果,javascript,typescript,recursion,Javascript,Typescript,Recursion,我有下面的代码来获取项目的所有名称,以便name1、name2、name3、name31、name32。。。依此类推,还可以根据某些条件将某些选定项设置为true或false。我试图用递归函数来解决这个问题。但我不知道如何坚持结果并在最后返回结果 arr = [ { name: 'name1', selected: true, children: [ { name: 'name2', selected: false, children:

我有下面的代码来获取项目的所有名称,以便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);

将结果移到函数之外,否则每次调用都会声明结果,其值将被重置。

您在递归调用中初始化了结果变量,该调用只返回初始值,所有迭代值将被忽略。
这就行了,

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);

您可以使用
Array.prototype.flatMap
-

const name=t=>
t、 平面图(v=>[v.name,…name(v.children)])
姓名(arr)
// ...

我强烈建议,对于您正在尝试做的两件事,查找名称列表和更改一些
select
值,您可以在两个单独的函数中完成它们

您总是可以编写一个包装器函数来同时完成这两个任务,但是这两个任务有不相关的需求;将它们结合起来会增加不必要的复杂性

这里已经有了一个很好的名称解决方案。请看“谢谢”的答案

对于另一项要求,我建议您将其分为三个不同的部分。“根据某些条件将某些选定项设置为true或false”是两个部分:一个用于测试您的条件,另一个用于进行更改。第三部分是实际遍历数据的代码。(另外,可能还有第四种情况;我下面的示例假设只有在条件为真时才对数据执行某些操作,但可以运行两种不同的操作:一种是真的,另一种是假的。)

你并没有描述你的情况,所以我会编一个。如果
名称
末尾的数字是奇数,我会说这个条件是真的。我们需要一个函数来返回
selected
设置为true的对象版本。以下是两个简单的辅助函数:

const nameIsOdd=({name})=>
编号(名称.替换(/\D/g'')%2==1
常量selectedTrue=({select,…rest})=>
({…rest,所选:true})
(请注意,我说我们返回一个具有更新属性的对象。我更喜欢以不可变的方式处理数据,并返回经过修改的结构版本,而不是对其进行更改。)

现在我们可以编写一个函数来递归遍历具有
子属性的对象数组,接受一个谓词函数和一个用于创建更新节点的函数。其实很简单:

constalternodes=(pred,change)=>(xs)=>
map({children=[],…rest})=>({
…(pred(rest)?change(rest):rest),
子节点:alterNodes(pred,change)(子节点)
}))
利用这一点,我们现在可以非常简单地编写主要函数:

const fixSelected = alterNodes (nameIsOdd, selectedTrue)
您可以在以下代码段中看到这一点:

constalternodes=(pred,change)=>(xs)=>
map({children=[],…rest})=>({
…(pred(rest)?change(rest):rest),
子节点:alterNodes(pred,change)(子节点)
}))
常量nameIsOdd=({name})=>
编号(名称.替换(/\D/g'')%2==1
常量selectedTrue=({select,…rest})=>
({…rest,所选:true})
const fixSelected=alterNodes(nameIsOdd,selectedTrue)
const arr=[{name:'name1',selected:true,children:[{name:'name2',selected:false,children:[{name:'name3',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控制台包装{max height:100%!important;top:0}
是的,但请注意,这只是问题的一半。有关另一半的方法,请参阅我的。
["name1", "name2", "name3", "name31", "name32", "name321", "name322", "name323", "name33", "name4"]
const fixSelected = alterNodes (nameIsOdd, selectedTrue)