搜索嵌套对象中特定键的值

时间:2018-03-31 08:18:11

标签: javascript arrays object recursion data-manipulation

我有这个嵌套对象:

{
    "PINS" : {
        "2017" : {
            "Nov-2017" : {
                "VJkRWX7pTSl_5w1Np" : {
                    "pin" : "6K3jP5vLyN",
                    "say": "Hello"
                },
                "MsdsXiO9G9mwM3Qa" : {
                    "pin" : "hnPKh7ywvT",
                    "say": "Hello"
                }
            },
            "Dec-2017" : {
                "Mm35Gjb-nY0k2TV" : {
                    "pin" : "xWwaNNE2XG",
                    "say": "Hello" 
                },
                "WzajCLEJmJHmzg0" : {
                    "pin" : "vMU1mKbZAi",
                    "say": "Hello"
                }
            }
        },
        "2018" : {
            "Jan-2018" : {
                "Wf8E1unVaOh03a43" : {
                    "pin" : "qXJCQREATD",
                    "say": "Hello"
                },
                "JZqP8fVCLSja6J82v" : {
                    "pin" : "o5D8S8Lvtb",
                    "say": "Hello"
                }
            },
            "Feb-2018" : {
                "lMMAKNLy8jtnnXAN" : {
                    "pin" : "9zDuHcw6qH",
                    "say": "Hello" 
                },
                "e9EV3HDKCceM" : {
                    "pin" : "kPllwcoaob",
                    "say": "Hello" 
                }
            }
        }
    }
}

我需要的是找到所有'pin'键,并获取它们的值,将它们放入数组中。

确切地说,我需要一个像这样的数组:

['6K3jP5vLyN', 'hnPKh7ywvT', 'xWwaNNE2XG', 'vMU1mKbZAi', 'qXJCQREATD', 'o5D8S8Lvtb', '9zDuHcw6qH', 'kPllwcoaob']

我试过了:

const array = [];

function iter(obj){
    for(key in obj){
        if(obj.pin)
        array.push(obj.pin);
        if(obj[key]!==null && typeof obj[key]==="object"){
            iter(obj[key]);
        }
    }
}
iter(obj);

但我得到每个键的值两次。有没有一些改进的方法来做到这一点?

2 个答案:

答案 0 :(得分:3)

您可以使用递归方法将嵌套对象展平为其叶值。

选项1 - 该值是指定的唯一属性(问题更新前的原始答案)

该方法使用Object.values()将当前值提取到数组。它使用Array.map()迭代数组,并展平作为对象的任何值。每次运行的结果都是spreadArray.concat()以展平嵌套数组。

const data = {"PINS":{"2017":{"Nov-2017":{"VJkRWX7pTSl_5w1Np":{"pin":"6K3jP5vLyN"},"MsdsXiO9G9mwM3Qa":{"pin":"hnPKh7ywvT"}},"Dec-2017":{"Mm35Gjb-nY0k2TV":{"pin":"xWwaNNE2XG"},"WzajCLEJmJHmzg0":{"pin":"vMU1mKbZAi"}}},"2018":{"Jan-2018":{"Wf8E1unVaOh03a43":{"pin":"qXJCQREATD"},"JZqP8fVCLSja6J82v":{"pin":"o5D8S8Lvtb"}},"Feb-2018":{"lMMAKNLy8jtnnXAN":{"pin":"9zDuHcw6qH"},"e9EV3HDKCceM":{"pin":"kPllwcoaob"}}}}};

const flattenObj = (obj) =>
  [].concat(...Object.values(obj).map((o) => typeof o === 'object' ? flattenObj(o) : o));
  
const result = flattenObj(data);

console.log(result);

选项2 - 该值不是叶子上的唯一属性

如果您的数据包含其他键,则此变体使用Object.entries()提取特定键:

const data = {"PINS":{"2017":{"Nov-2017":{"VJkRWX7pTSl_5w1Np":{"pin":"6K3jP5vLyN","say":"Hello"},"MsdsXiO9G9mwM3Qa":{"pin":"hnPKh7ywvT","say":"Hello"}},"Dec-2017":{"Mm35Gjb-nY0k2TV":{"pin":"xWwaNNE2XG","say":"Hello"},"WzajCLEJmJHmzg0":{"pin":"vMU1mKbZAi","say":"Hello"}}},"2018":{"Jan-2018":{"Wf8E1unVaOh03a43":{"pin":"qXJCQREATD","say":"Hello"},"JZqP8fVCLSja6J82v":{"pin":"o5D8S8Lvtb","say":"Hello"}},"Feb-2018":{"lMMAKNLy8jtnnXAN":{"pin":"9zDuHcw6qH","say":"Hello"},"e9EV3HDKCceM":{"pin":"kPllwcoaob","say":"Hello"}}}}};

const flattenObjKey = (obj, key) =>
  [].concat(...Object.entries(obj)
    .map(([k, v]) => typeof v === 'object' ? 
      flattenObjKey(v, key) : (k === key ? v : [])
    ));
  
const result = flattenObjKey(data, 'pin');

console.log(result);

答案 1 :(得分:0)

看起来你的数据结构一致,所以这很简单。

const pins = [];
for (let year in pins) {
    for (let month in year) {
        for (let key in months) {
            pins.push(key.pin);
        }
    }
}

如果结构不一致,您需要提取寻找密钥的递归解决方案。