Javascript 递归地在数组中查找项,并从引用数组中剪接找到的项

Javascript 递归地在数组中查找项,并从引用数组中剪接找到的项,javascript,arrays,recursion,tree,javascript-objects,Javascript,Arrays,Recursion,Tree,Javascript Objects,我试图递归地在一个对象数组中查找项,然后重建同一个数组,但不在其中找到项。找到该项后,我希望将其从引用数组中拼接出来。下面是我的尝试,但不幸的是它根本不起作用 var tt=[{age:4,els:[{age:12,els:[]},{age:32,els:[{age:44,els:[]},{age:100,els:[{age:3,els:[],age:22,els:[{age:13,els:[]},{age:99,els:[]},{age:88,els:[{age:16,els:[]}}},{

我试图递归地在一个对象数组中查找项,然后重建同一个数组,但不在其中找到项。找到该项后,我希望将其从引用数组中拼接出来。下面是我的尝试,但不幸的是它根本不起作用

var tt=[{age:4,els:[{age:12,els:[]},{age:32,els:[{age:44,els:[]},{age:100,els:[{age:3,els:[],age:22,els:[{age:13,els:[]},{age:99,els:[]},{age:88,els:[{age:16,els:[]}}},{age:223 els:[]},{age:120,els:[]age:300,els:[][{年龄:400,els:[]}]}];
kk=[];
var测试=功能(els){
对于(变量i=0;iconsole.log(kk);//--在不显示新找到项的情况下显示新数组
虽然目标很崇高,但我认为建议的设计不是一个合理的选择。这里有一些违规行为:

  • 已损坏。通过
    test
    仅使用特定名称
    kk
    填充全局,我们不必要地将函数绑定到单个上下文,使其无法使用
  • 通过返回一个值并生成一个值,
    test
    函数变得难以推理
  • 没有理由不使用child key和target removation value参数来泛化
    test
    (让我们调用函数
    filterRecursive
    )。例如,此函数应该与任意回调谓词一起工作
  • 这些变量名并不是非常具有描述性的选择,但我假设这只是出于问题的目的
下面是一个如何处理的建议。我返回一个包含
result
removed
键的对象(我不太喜欢,但它总比副作用好)它允许您访问更新的结构以及所有未通过谓词的已删除对象的展开列表。原始数组不会发生变化

const数据=[
{
年龄:1,,
els:[{
年龄:2岁,
els:[]
}, {
年龄:3岁,
els:[{
年龄:4岁,
els:[]
}, {
年龄:5岁,
els:[]
}]
}]
},
{
年龄:6岁,
els:[]
}
];
常量filterRecursive=(arr,谓词,childKey,removed=[])=>{
删除.push(…arr.filter(e=>!谓词(e));
const result=arr.filter(谓词).map(e=>{
if(e[childKey]){
const{result:sub}=filterRecursive(e[childKey],谓词,childKey,已删除);
返回{…e[childKey]:sub};
}
返回e;
});
返回{result:result,removed:removed};
};
const{result,removed}=filterRecursive(数据,e=>![4,6]。包括(e.age),“els”);
console.log(“原始”,数据);
console.log(“结果”,result);
log(“已删除”,已删除);
这是一个有趣的例子。 下面是我的代码

var tt = [{ age: 4, els: [{ age: 12, els: [] }, { age: 400, els: [{ age: 44, els: [] }, { age: 100, els: [{ age: 3, els: [], age: 22, els: [{ age: 13, els: [] }, { age: 99, els: [] }, { age: 88, els: [{ age: 16, els: [] }] }] }] }] }] }, { age: 223, els: [] }, { age: 120, els: [{ age: 300, els: [] }, { age: 301, els: [{ age: 400, els: [] }] }] }];



var test = function(els) {
  const newEls = []
  for (var i = 0; i < els.length; i++) {
    if (els[i].age == 400) {
      console.log('found');
      console.log(els[i]);
    } else {
      newEls.push({
        age: els[i].age,
        els: test(els[i].els)
      })
    }
  }
  return newEls
}

console.log(tt) // -- show original array
const kk = test(tt); // -- show found item
console.log(kk); // -- show new array without the newly found item
var tt=[{age:4,els:[{age:12,els:[]},{age:400,els:[{age:44,els:[]},{age:100,els:[{age:3,els:[],age:22,els:[{age:13,els:[]},{age:99,els:[]},{age:88,els:[{age:16,els:[]}}}},{age:223 els:[]},els:[]},{age:120,els:[]age:13,els:[]},els:[]},els:[]},{age:300,els:[]},{age:[]}age:400,els:[]}]] }];
var测试=功能(els){
常数newEls=[]
对于(变量i=0;i
因为在
测试()
for
循环中有一个返回,它将中断循环但不返回任何内容。您应该
从for循环中返回

由于使用
test()
进行递归调用,因此最好定义另一个数组来保存找到的项,然后使用
console.log
保存它

var tt=[{age:4,els:[{age:12,els:[]},{age:32,els:[{age:44,els:[]},{age:100,els:[{age:3,els:[],age:22,els:[{age:13,els:[]},{age:99,els:[]},{age:88,els:[{age:16,els:[]}}},{age:223 els:[]},{age:120,els:[]age:300,els:[][{年龄:400,els:[]}]}];
var kk=[];
var-mm=[];
var测试=功能(els){
对于(变量i=0;iconsole.log(kk);//--显示不带新找到项的新数组
我将对此使用递归reduce。在迭代过程中,跳过
.age==400的所有项,然后返回,对
.els
执行相同的过程:

const remove=xs=>
xs.reduce((ret,{age,els})=>
年龄===400
?ret
:ret.concat({age,els:remove(els)}),
[]);
console.log(
删除(数据)
);

常数数据=[
{年龄:4岁,els:[
{年龄:12岁,els:[]},
{年龄:32岁,els:[
{年龄:44,els:[]},
{年龄:100,els:[
{年龄:3岁,els:[]},
{年龄:22,els:[
{年龄:13岁,els:[]},
{年龄:99,els:[]},
{年龄:88,els:[
{年龄:16,els:[]}]}]}]}]},
{年龄:223,els:[]},
{年龄:120,els:[
{年龄:300,els:[]},
{年龄