【问题标题】:Find the value inside the array of objects that include children from the array of objects在对象数组中查找包含对象数组中的子项的值
【发布时间】:2018-12-20 09:13:53
【问题描述】:

我有一个对象数组,其中包括对象数组中的子对象,我需要在父数组中查找值或在该数组的子对象中查找值等。也许是递归的。我试过这样:

var array = [
  {
    id: 1,
    value: 'value',
    children: null
  },
  {
    id: 2,
    value: 'my value',
    children: [
      {
        id: 'child1',
        value: 'my value',
        children: null
      },
      {
        id: 'child2',
        value: 'value',
        children: null
      },
      {
        id: 'child3',
        value: 'value,
        children: [
          {
            id: 'childchild1',
            value: 'my value',
            children: null
          }
        ]
      }
    ]
  },
  {
    id: 3,
    value: 'value',
    children: null
  },
  {
    id: 4,
    value: 'my value',
    children: null
  }
]


function find(searchData, target){
  return target.filter((f)=>{
    if(f.value.includes(searchData)){
      return true
    }
    if(f.children){
      return find(searchData, f.children)
    }
  })
}

find('my', array)

它返回源数组,但我需要包含文本“我的”的数组

【问题讨论】:

  • @CertainPerformance 是,但不是儿童
  • 请包含您给出的示例所需的输出。

标签: javascript arrays ecmascript-6


【解决方案1】:

因为你有一个嵌套结构,所以你不能使用.filter 来获取所有嵌套对象 - .filter 只会返回给你最顶层的匹配对象。相反,在初始调用时定义一个空数组,然后在项目通过测试时将push 传递给该数组,并将该数组传递给每个递归调用。最后,返回该数组:

var array=[{id:1,value:'value',children:null},{id:2,value:'my value',children:[{id:'child1',value:'my value',children:null},{id:'child2',value:'value',children:null},{id:'child3',value:'value',children:[{id:'childchild1',value:'my value',children:null}]}]},{id:3,value:'value',children:null},{id:4,value:'my value'}];

function find(searchData, target, accum=[]){
  target.forEach((f)=>{
    if(f.children){
      find(searchData, f.children, accum)
    }
    if(f.value.includes(searchData)){
      accum.push(f);
    }
  });
  return accum;
}

console.log(find('my', array));

(通过浏览器控制台可能比通过堆栈 sn-p 控制台更容易看到结果)

【讨论】:

    【解决方案2】:

    这是一个函数式编程风格的实现。为了简化输出,我刚刚收集了匹配项的 id 值。如果您想要整个对象,请将obj.id 替换为obj

    const array = [{id: 1,value: 'value',children: null},{id: 2,value: 'my value',children: [{id: 'child1',value: 'my value',children: null},{id: 'child2',value: 'value',children: null},{id: 'child3',value: 'value' ,children: [{id: 'childchild1',value: 'my value',children: null}]}]},{id: 3,value: 'value',children: null},{id: 4,value: 'my value'}];
    
    const find = (searchData, target) => (target || []).reduce(
            (acc, obj) => acc.concat(obj.value.includes(searchData) ? obj.id : [],
                                     find(searchData, obj.children)),
            []
        );
    
    const result = find('my', array);
    console.log(result);

    【讨论】:

    • 哇,这是非常漂亮和简短的代码。我要多练习
    【解决方案3】:

    有点晚了,这里又是递归查找:

    var array = [
      {
        id: 1,
        value: 'value',
        children: null,
      },
      {
        id: 2,
        value: 'my value',
        children: [
          {
            id: 'child1',
            value: 'my value',
            children: null,
          },
          {
            id: 'child2',
            value: 'value',
            children: null,
          },
          {
            id: 'child3',
            value: 'value',
            children: [
              {
                id: 'childchild1',
                value: 'my value',
                children: null,
              },
            ],
          },
        ],
      },
      {
        id: 3,
        value: 'value',
        children: null,
      },
      {
        id: 4,
        value: 'my value',
      },
    ];
    
    function find(search, arr) {
      function recur(result, search, arr) {
        if (!(arr && arr.length)) {
          return result;
        }
        return result
          .concat(
            ...arr.filter((item) =>
              item.value.includes(search),
            ),
          )
          .concat(
            ...arr.map((item) =>
              recur([], search, item.children),
            ),
          );
      }
      return recur([], search, arr);
    }
    console.log(find('my', array));

    【讨论】:

    • 这是一个很好的解决方案,但代码更长。不过还是谢谢:)
    猜你喜欢
    • 1970-01-01
    • 2021-09-07
    • 1970-01-01
    • 2015-03-15
    • 1970-01-01
    • 2021-08-28
    • 1970-01-01
    • 2019-07-26
    • 1970-01-01
    相关资源
    最近更新 更多