简体   繁体   English

在任意深度的嵌套数组中查找值

[英]Finding a Value in an Nested Array of Arbitrary Depth

Currently refactoring some javascript (ES6) logic, I've come across a scenario where I need to search an nested array of arbitrary depth to find certain elements, check with a helper function, and set a boolean based on the results of the helper. 当前正在重构一些javascript(ES6)逻辑,我遇到一种情况,我需要搜索一个任意深度的嵌套数组以查找某些元素,使用帮助函数进行检查,并根据帮助结果设置布尔值。

let hit_possibilities = ["CASE1", "CASE2"];
let target =
    [
        "cat",
        "dog",
        [
            "CASE1",
            [
                "dad",
                "CASE2"
            ],
            "mom"
        ],
        "pam"
    ]

The above variables represent both aforementioned arrays. 以上变量代表上述两个数组。

I need a function that take in both a target array (which can be of any depth and any object order) and a hit_possibilities array to check if any of the elements in hit_possibilities exists in the target array. 我需要一个同时包含目标数组(可以是任意深度和任何对象顺序)和hit_possibilities数组的函数,以检查hit_possibilities中是否有任何元素存在于目标数组中。 If the function hits an element that is in the hit_possibilities, it calls another function that returns true or false (contents not relevant, just an already written helper). 如果该函数命中了hit_possibilities中的元素,则它将调用另一个返回true或false的函数(内容无关紧要,只是一个已编写的帮助程序)。 If false is returned, the function breaks immediately, returning false. 如果返回false,则函数立即中断,返回false。 If true is returned, the function continues down the array; 如果返回true,则函数继续在数组中向下; if arriving at no circumstance of a false return, the function return true. 如果没有出现错误返回的情况,则该函数返回true。

Here's an iterative (non-stack overflow) solution that runs a depth-first search on the structure. 这是一个迭代(非堆栈溢出)解决方案,它对结构进行深度优先搜索 Note that I used a set for fast lookups: 请注意,我使用了一用于快速查找:

 let hitPossibilities = ["CASE1", "CASE2"]; let target = [ "cat", "dog", [ "CASE1", [ "dad", "CASE2" ], "mom" ], "pam" ]; const helper = e => false; // stub const search = (needles, haystack) => { const set = new Set(needles); const stack = [haystack]; while (stack.length) { const curr = stack.pop(); for (let i = 0; i < curr.length; i++) { if (Array.isArray(curr[i])) { stack.push(curr[i]); } else if (set.has(curr[i]) && !helper(curr[i])) { return false; } } } return true; }; console.log(search(hitPossibilities, target)); console.log(search(["FOO", "BAR"], target)); 

As an alternative to @ggorlen, but with recursion method it would look something like this: 作为@ggorlen的替代方法,但是使用递归方法,它将看起来像这样:

let hitPossibilities = ["CASE1", "CASE2"];
let target =
    [
        "cat",
        "dog",
        [
            "CASE1",
            [
                "dad",
                "CASE2"
            ],
            "mom"
        ],
        "pam"
    ]

function search(target, hit) {
  for (let i = 0; i < target.length; ++i) {
    currTarget = target[i];

    if(Array.isArray(currTarget)) {
       if(!search(currTarget, hit)){
         return false;
       }
    } else {
      for(let j = 0; j < hit.length; ++j) {
        let currHit = hit[j];

        if(currTarget === currHit) {
          if(!isValid()) {
            return false;
          }
        }
      }
    }
  }
  return true;
}

// Your function here...
function isValid() {
  return true; // put false to test the differet output.
}

console.log(search(target, hitPossibilities));

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

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