代码之家  ›  专栏  ›  技术社区  ›  robe007 Leo Aguirre

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

  •  1
  • robe007 Leo Aguirre  · 技术社区  · 6 年前

    我有一个嵌套对象:

    {
        "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 回复  |  直到 6 年前
        1
  •  3
  •   Ori Drori    6 年前

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

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

    该方法使用将当前值提取到数组中 Object.values() 。它使用 Array.map() ,并展平作为对象的任何值。每次运行的结果是 spread 进入 Array.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);
        2
  •  0
  •   Jonny Rathbone    6 年前

    看起来您的数据结构一致,所以这相当简单。

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

    如果它的结构不一致,则需要提取一个查找pin键的递归解决方案。