繁体   English   中英

遍历获取密钥和所有父密钥的对象

[英]Traversing an object getting the key and all parents keys

遍历树(json),使用JS实现getKeys(data,str)函数。 获取密钥和所有父母密钥。

const data = {
  key1: 'str1',
  key2: {
    key3: 'str3',
    key4: 'str4',
    key5: {
      key6: 'str6',
      key7: 'str7',
      key8: 'str8',
    },
  }
}

例如:

getKeys(data,'str1'); 返回:'key1'

getKeys(data,'str3'); return:'key2,key3'

getKeys(data,'str6'); return:'key2,key5,key6'

我认为它可以做到递归,但是如何?

这是我的解决方案,但失败了

let s = [];
function getKeys(data, str, key='') {
  if (key !== '') {
    s.push(key);
  }
  for (item in data) {
    if (typeof data[item] === 'object') {
      getKeys(data[item], str, item);
    } else if (data[item] === str) {
      s.push(item);
      return s;
    }
  }
  return s;
}

代码的问题在于它无条件地填充“找到”列表,无论该值是否实际位于当前处理的分支之下。 考虑例如:

data = {
    a: 1,
    b: {
        c: 2
    },
    d: {
        e: {
            e1: 3,
            e2: 33,
        },
        f: {
            f1: 4,
            f2: 44,
        },
    }
};

当做getKeys(data, 44) ,返回将是[ 'b', 'd', 'e', 'f', 'f2' ] ,这是不正确的。

您需要做的是检查该值是否实际位于当前节点下,并仅在答案为是时添加当前键。 例:

function getKeys(obj, val) {
    if (!obj || typeof obj !== 'object')
        return;

    for (let [k, v] of Object.entries(obj)) {
        if (v === val)
            return [k];
        let path = getKeys(v, val);
        if (path)
            return [k, ...path];

    }
}

假设您只搜索string键,我们可以使用递归和回溯来检查键的子对象是否具有指定的值。

如果有,则在我们的最终搜索字符串中添加父键。

为此,我使用Object.entries()遍历每个[key, value]对,并使用Array.prototype.reduce()来累积结果:

 var data = { key1: 'str1', key2: { key3: 'str3', key4: 'str4', key5: { key6: 'str6', key7: 'str7', key8: 'str8', }, } } function getKeys(data, key, acc){ return Object.entries(data).reduce((acc, ele, idx) => { if(ele.includes(key) && typeof ele[1] === "string"){ acc.push(ele[0]); } if(typeof ele[1] === "object" && !Array.isArray(ele[1]) && !(ele[1] instanceof Date)){ let old = acc.slice(); getKeys(ele[1], key, acc); if(old.length !== acc.length){ acc.unshift(ele[0]); } } return acc; }, acc).join(" "); } console.log(getKeys(data, 'str1', [])); console.log(getKeys(data, 'str3', [])); console.log(getKeys(data, 'str6', [])); 

暂无
暂无

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

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