遍历JavaScript数组并动态查找深层嵌套的值

时间:2020-07-24 22:51:49

标签: javascript arrays loops object

我目前正在手动遍历数组并进行越来越深的嵌套循环以比较值,但是我很好奇是否有任何方法可以自动执行此搜索?我需要找到深层嵌套的数组,比较1或2个值,然后还可以修改这些值。

示例数组。

searchableArray = [];

searchableArray.push({id: 3, type: 'some-type', text: 'text', nestedElements: [{id: 4, type: 'some-type', text: 'other text', nestedElements: []}, {id: 5, type: 'another-type',  text: 'more text', nestedElements: []}]})
searchableArray.push({id: 6, type: 'other-type', text: 'text', nestedElements: [{id: 7, type: 'other-type', text: 'other text', nestedElements: []}, {id: 8, type: 'another-type',  text: 'more text', nestedElements: []}]})
searchableArray.push({id: 9, type: 'another-type', text: 'text', nestedElements: [{id: 10, type: 'another-type', text: 'other text', nestedElements: []}, {id: 11, type: 'another-type',  text: 'more text', nestedElements: []}]})

基本上,我需要搜索id(它在整个数组和对象中都是唯一的,但是可以嵌套在另一个数组内的对象内部的各个层次中。但是始终被称为“ nestedElements”。

我需要能够找到ID,然后修改ID所属的对象,并将其放回我正在使用的数组中。

现在,我只是为每个潜在的嵌套数组制作手动循环。 (其中有很多多余的复制粘贴代码)

for(var i = 0; i < searchableArray.length; ++i) 
{
    if(searchableArray[i].id == 6) //6 would actually be a variable, just doing a manual example
    {
        if(searchableArray[i].nestedElements.length > 0)
        {
            for(var j = 0; j < searchableArray[i].nestedElements.length; ++j) 
            {
                if(searchableArray[i].nestedElements[j].id == '7')
                {
                    if(searchableArray[i].nestedElements[j].type == 'other-type')
                    {
                        searchableArray[i].nestedElements[j].dosomething = 'do this to something in the object';
                    }
                    else if(searchableArray[i].nestedElements[j].type == 'another-type')
                    {
                        searchableArray[i].nestedElements[j].dosomething = 'do this other thing to the object';
                    }
                }
            }
        }
    }
}

对于所有内容而言,嵌套循环都会变得非常庞大,那么有没有更简单的方法呢?

谢谢!

4 个答案:

答案 0 :(得分:1)

您可以通过一些代码重构来简化结构:

  1. if运算符可以避免嵌套&&
  2. 您可以避免内部for循环,而应使用find

let searchableArray = [];

searchableArray.push({id: 3, type: 'some-type', text: 'text', nestedElements: [{id: 4, type: 'some-type', text: 'other text', nestedElements: []}, {id: 5, type: 'another-type',  text: 'more text', nestedElements: []}]})
searchableArray.push({id: 6, type: 'other-type', text: 'text', nestedElements: [{id: 7, type: 'other-type', text: 'other text', nestedElements: []}, {id: 8, type: 'another-type',  text: 'more text', nestedElements: []}]})
searchableArray.push({id: 9, type: 'another-type', text: 'text', nestedElements: [{id: 10, type: 'another-type', text: 'other text', nestedElements: []}, {id: 11, type: 'another-type',  text: 'more text', nestedElements: []}]})


searchableArray.forEach(item => {
    if(item.id === 6 && item.nestedElements.length > 0 && item.nestedElements.find(item => item.id === 7 && item.type === "other-type")){
        item.nestedElements.find(item => item.id === 7 && item.type === "other-type").dosomething = 'do this to something in the object';       
    } else if (item.id === 6 && item.nestedElements.length > 0 && item.nestedElements.find(item => item.id === 7 && item.type === "another-type")){
        item.nestedElements.find(item => item.id === 7 && item.type === "another-type").dosomething = 'do this other thing to the object';
    }   
});

console.log(searchableArray);

答案 1 :(得分:1)

这就是您想要的:

const searchableArray = [];

searchableArray.push({ id: 3, type: 'some-type', text: 'text', nestedElements: [{ id: 4, type: 'some-type', text: 'other text', nestedElements: [] }, { id: 5, type: 'another-type', text: 'more text', nestedElements: [] }] })
searchableArray.push({ id: 6, type: 'other-type', text: 'text', nestedElements: [{ id: 7, type: 'other-type', text: 'other text', nestedElements: [] }, { id: 8, type: 'another-type', text: 'more text', nestedElements: [] }] })
searchableArray.push({ id: 9, type: 'another-type', text: 'text', nestedElements: [{ id: 10, type: 'another-type', text: 'other text', nestedElements: [] }, { id: 11, type: 'another-type', text: 'more text', nestedElements: [] }] });

const find = (id, cb) => {
    const ar = searchableArray.slice(0);
    for (var i = 0; i < ar.length; i++) {
        if (ar[i].id === id) {
            return cb(ar[i]);
        }
        if (ar[i].nestedElements.length) {
            ar.push(...ar[i].nestedElements);
        }
    }

}

find(7, (o) => {
    if (o.type == 'other-type') {
        o.dosomething = 'do this to something in the object';
    } else if (o.type == 'another-type') {
        o.dosomething = 'do this other thing to the object';
    }
});

console.log(JSON.stringify(searchableArray));

答案 2 :(得分:0)

示例:

searchableArray.forEach(function(el){
                    if (el.hasOwnProperty("nestedElements") && el.nestedElements instanceof Array){
                        el.nestedElements.forEach(function(el1){
                           if (el1.id===7){
                               
                           }
                        });
                    }
            });

答案 3 :(得分:0)

这些天,我们尽量不要过度发明,为此建议object-scan。一旦将头缠住它,它就会非常强大。这是您的使用方式:

const objectScan = require('object-scan');

const modify = (id, task, data) => objectScan(['**.id'], {
  abort: true,
  rtn: 'bool',
  filterFn: ({ value, parent }) => {
    if (value === id) {
      task(parent);
      return true;
    }
    return false;
  }
})(data);

const searchableArray = [{"id":3,"type":"some-type","text":"text","nestedElements":[{"id":4,"type":"some-type","text":"other text","nestedElements":[]},{"id":5,"type":"another-type","text":"more text","nestedElements":[]}]},{"id":6,"type":"other-type","text":"text","nestedElements":[{"id":7,"type":"other-type","text":"other text","nestedElements":[]},{"id":8,"type":"another-type","text":"more text","nestedElements":[]}]},{"id":9,"type":"another-type","text":"text","nestedElements":[{"id":10,"type":"another-type","text":"other text","nestedElements":[]},{"id":11,"type":"another-type","text":"more text","nestedElements":[]}]}];

console.log(modify(7, (obj) => {
  if (obj.type === 'other-type') {
    obj.dosomething = 'do this to something in the object';
  } else if (obj.type === 'another-type') {
    obj.dosomething = 'do this other thing to the object';
  }
}, searchableArray)); // true iff executed
// => true

console.log(JSON.stringify(searchableArray));
// => [{"id":3,"type":"some-type","text":"text","nestedElements":[{"id":4,"type":"some-type","text":"other text","nestedElements":[]},{"id":5,"type":"another-type","text":"more text","nestedElements":[]}]},{"id":6,"type":"other-type","text":"text","nestedElements":[{"id":7,"type":"other-type","text":"other text","nestedElements":[],"dosomething":"do this to something in the object"},{"id":8,"type":"another-type","text":"more text","nestedElements":[]}]},{"id":9,"type":"another-type","text":"text","nestedElements":[{"id":10,"type":"another-type","text":"other text","nestedElements":[]},{"id":11,"type":"another-type","text":"more text","nestedElements":[]}]}]