如何遍历深层嵌套对象并找到特定键的值?

时间:2020-11-01 00:34:22

标签: javascript node.js json foreach collections

我有一个如下所示的Javascript对象。 我想遍历该对象并找出Hostnames

的值
const data =
{
  "error1": {
    "7": [
      {
        "ErrorType": "Error-1A",
        "Hostnames": "host123.com,hostabc.com,host33a.com..."
      }
    ],
    "8": [
      {
        "ErrorType": "Error-1B",
        "Hostnames": "host223.com,host2c.com,host43a.com..."
      },
      {
        "ErrorType": "Error-1C",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error2": {
    "3": [
      {
        "ErrorType": "Error-2A"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2B"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ],
    "8": [
      {
        "ErrorType": "Error-2C"
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      },
      {
        "ErrorType": "Error-2D",
        "Hostnames": "host1231.com,host2abc.com,host313a.com..."
      }
    ]
  },
  "error3": {
    "1": [
      {
        "ErrorType": "Error-3A",
        "Hostnames": "host1236.com"
      },
      {
        "ErrorType": "Error-3B",
        "Hostnames": "hostc3231.com"
      }
    ]
  }
}

我编写了以下NodeJS函数:

const findObjectByLabel = function(obj, label) {
    if(obj.label === label) { return obj; }
    for(var i in obj) {
        if(obj.hasOwnProperty(i)){
            var foundLabel = findObjectByLabel(obj[i], label);
            if(foundLabel) { return foundLabel; }
        }
    }
    return null;
};

const hostNames = findObjectByLabel(data, 'Hostnames');
console.log(hostNames);

上面的函数抛出错误:

Error: undefined : RangeError: Maximum call stack size exceeded

2 个答案:

答案 0 :(得分:1)

因此,让我们删除无用的上下文。您想深入地在对象中找到“主机名”值。

您的递归似乎循环,导致最大调用堆栈大小超出错误。

您如何独自找到问题?只需在“ findObjectByLabel”函数的第一行中添加“ console.log('ON',obj)”即可。

您将看到在“ E”上循环。因为在某些时候,被测试的对象是字符串。

第二个问题:您检查.label ==='Hostnames'... json数据中没有'label'键。

解决此问题后的另一个问题是,您将停止使用第一个主机名。

这是一个解决方案

function deepFind(obj, label, results=[]) {
    if( typeof obj !== 'object' && !!obj )
      return null;

    if( !!obj[label] ) {
      results.push(obj[label]);
    }

    Object.getOwnPropertyNames(obj).forEach( k => {
      deepFind(obj[k], label, results);
    });
}

const results = [];
deepFind(data, 'Hostnames', results);

不优雅,但可以使用

答案 1 :(得分:1)

数据结构需要嵌套循环,但这是可行的。这将为此提供一个主机名数组:“ 我要遍历该对象并找出主机名的值”。

fn delete(&mut self, key: &String) -> Option<i32> {
  if key.is_empty() { 
    return None
  }
  // clone `self.root`
  let mut current_node = self.root.clone();
  for (ind, ch) in key.chars().enumerate() {
  match current_node.chs.get_mut(&ch) {
    Some(node) => {
      if ind < key.len() - 1 {
      // clone `node`
        current_node = node.clone();
      }
    // ...