简体   繁体   English

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

[英]Traverse JavaScript array and dynamically find deep nested values

I am currently manually looping through an array and doing deeper and deeper nested loops to compare values, but I am curious if there is any way to do this search automatically?我目前正在手动循环遍历数组并进行越来越深的嵌套循环来比较值,但是我很好奇是否有任何方法可以自动进行此搜索? I need to find deep nested arrays, compare 1 or 2 values and then also be able to modify the values.我需要找到深层嵌套的 arrays,比较 1 或 2 个值,然后还可以修改这些值。

Example array.示例数组。

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: []}]})

Basically I need to search for id (It will be unique throughout the entire array and object, but could be nested various levels deep inside an object inside another array. But will always be called "nestedElements".基本上我需要搜索 id (它将在整个数组和 object 中是唯一的,但可以嵌套在 object 深处的各个级别内部另一个数组中。但总是被称为“nestedElements”。

I need to be able to find the ID and then modify the object that ID belongs too and put it back in the array I am using.我需要能够找到 ID,然后修改 ID 所属的 object 并将其放回我正在使用的数组中。

Right now I am just making manual loops for each potential nested array.现在我只是为每个潜在的嵌套数组制作手动循环。 (Which is a lot of extra copy paste code) (这是很多额外的复制粘贴代码)

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';
                    }
                }
            }
        }
    }
}

This would get very huge with nested loops for everything, so is there any easier way to do it?对于所有内容的嵌套循环,这将变得非常庞大,那么有没有更简单的方法来做到这一点?

Thanks!谢谢!

Example:例子:

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

You can simplify your structure by some code refactoring:您可以通过一些代码重构来简化您的结构:

  1. Nested if can be avoided by && operator.嵌套if可以通过&&运算符避免。
  2. You can avoid the inner for loop and use find instead.您可以避免内部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);

This is what you want:这就是你想要的:

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

We try not to reinvent too much these days and I'd suggest object-scan for this.这些天我们尽量不要重新发明太多,我建议为此进行对象扫描 It's pretty powerful once you wrap your head around it.一旦你把头绕在它周围,它就非常强大。 Here is how you'd use it:以下是您的使用方法:

 // 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(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: [] } ] } ]
 .as-console-wrapper {max-height: 100%;important: top: 0}
 <script src="https://bundle.run/object-scan@13.8.0"></script>

Disclaimer : I'm the author of object-scan免责声明:我是对象扫描的作者

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM