在对象中查找键值

时间:2018-11-21 07:03:42

标签: javascript json

我有以下对象(Json):

 let object = {
"statusCode": 200,
"body": [{
        "id": "3",
        "externalId": "yehudakala4",
        "status": "active",
        "createdAt": "2018-11-14T08:36:50.967Z",
        "updatedAt": "2018-11-14T08:36:50.967Z",
        "firstName": "yehu",
        "lastName": "da",
        "email": "ye@g.com"
    }
],
"headers": {
    "x-powered-by": "Express",
    "access-control-allow-origin": "*",
    "content-type": "application/json; charset=utf-8",
    "content-length": "189",
    "etag": "W/\"bd-Emx3/KChQLzf9+6bgFSHXPQgDTM\"",
    "date": "<<Masked>>",
    "connection": "close"
},
"request": {
    "uri": {
        "protocol": "http:",
        "slashes": true,
        "auth": null,
        "host": "user-management-service.dev.local:4202",
        "port": "4202",
        "hostname": "user-management-service.dev.local",
        "hash": null,
        "search": "?username=yehudakala4",
        "query": "username=yehudakala4",
        "pathname": "/v1/users",
        "path": "/v1/users?username=yehudakala4",
        "href": "http://user-management-service.dev.local:4202/v1/users?username=yehudakala4"
    },
    "method": "GET",
    "headers": {
        "Content-Type": "application/json",
        "accept": "application/json",
        "content-length": 2
    }
}

}

具有以下功能:

let key = "protocol";
let value = "http:";
let x;
let res = false;
let findValue = function findValue(obj, key, value) {

for(let localKey in obj){
    if(obj.hasOwnProperty(localKey)){
        //console.log(localKey)
        if(localKey === key){
            res = obj[localKey] === value;
            return res;
        }
        else
        {
            let val = obj[localKey];
            if(typeof val === 'object')
                x = findValue(val, key, value);
                if (typeof x === 'boolean') {
                    return x;
                }         
            }
        }
    }
}

let rs = findValue(object, key, value)
console.log(rs);

此方法存在两个问题:

  1. 如果键在对象中不存在,则函数返回undefine
  2. 如果密钥出现不止一次,则仅第一次检查

我的目标也是检查是否出现了任何键,如果其中之一的值不匹配,则返回false,如果所有匹配的结果都返回true。

第二次,如果密钥不存在,则返回false。

4 个答案:

答案 0 :(得分:1)

我将您的函数更改为通过在递归中包含Set作为上下文来获取给定键的所有值。

然后,您在set上检查single value that equals your value

查看更新的代码段。

最后,作为一个补充说明,Object.keys将使您的代码更加精简,因为您不必检查hasOwnProperty

let findValues = function(obj, key, found) {
  for (let localKey in obj) {
    if (obj.hasOwnProperty(localKey)) {
      let val = obj[localKey];
      //console.log(localKey)
      if (localKey === key) {
        found.add(val)
      } else {
        if (typeof val === 'object') {
          findValues(val, key, found)
        }
      }
    }
  }
}

function uniqueValue(obj, key, value) {
  let found = new Set()
  findValues(object, key, found)
  return found.size === 1 && found.has(value);
}

let object = {
  "statusCode": 200,
  "body": [{
    "id": "3",
    "externalId": "yehudakala4",
    "status": "active",
    "createdAt": "2018-11-14T08:36:50.967Z",
    "updatedAt": "2018-11-14T08:36:50.967Z",
    "firstName": "yehu",
    "lastName": "da",
    "email": "ye@g.com"
  }],
  "headers": {
    "x-powered-by": "Express",
    "access-control-allow-origin": "*",
    "content-type": "application/json; charset=utf-8",
    "content-length": "189",
    "etag": "W/\"bd-Emx3/KChQLzf9+6bgFSHXPQgDTM\"",
    "date": "<<Masked>>",
    "connection": "close"
  },
  "request": {
    "uri": {
      "protocol": "http:",
      "slashes": true,
      "auth": null,
      "host": "user-management-service.dev.local:4202",
      "port": "4202",
      "hostname": "user-management-service.dev.local",
      "hash": null,
      "search": "?username=yehudakala4",
      "query": "username=yehudakala4",
      "pathname": "/v1/users",
      "path": "/v1/users?username=yehudakala4",
      "href": "http://user-management-service.dev.local:4202/v1/users?username=yehudakala4"
    },
    "method": "GET",
    "headers": {
      "Content-Type": "application/json",
      "accept": "application/json",
      "content-length": 2
    }
  }
}

let key = "protocol";
let value = "http:";

console.log(uniqueValue(object, key, value));

答案 1 :(得分:0)

您可以为该问题创建一个简单的递归函数。它将查找并验证属性的值。片段中下面提到的功能将:

  • 如果找到该属性并且所有出现的属性都具有相同的值,则返回true。
  • 如果找不到该属性或所有出现的属性都不匹配,则返回false。

此函数当前仅支持对象,即它仅在对象中而不是在数组内部递归检查属性,我们可以进一步扩展它以支持数组。

let object1 = { auth : "ok", response : { auth : "ok" }, check : { check1 : { check2 : {auth : "no"} } } };
let object2 = { auth : "ok", response : { auth : "ok" }, check : { check1 : { check2 : {auth : "ok"} } } };


function findAndValidateKey(obj, targetKey, value, res){
  for(var key in obj){
    if(obj.hasOwnProperty(key) && key === targetKey){
      if(res === undefined)
        res = true;
      res = res && (obj[key] === value);
    } else if(obj[key] instanceof  Object && !Array.isArray(obj[key])){
      let tempResult = findAndValidateKey(obj[key], targetKey, value, res);
      if(res === undefined)
        res = true;
      res = res && tempResult;
    }
  }
  return !!res;
}
console.log(findAndValidateKey(object1, "auth","ok", undefined));
console.log(findAndValidateKey(object2, "auth","ok", undefined));

您还可以通过使用Stack数据结构来实现此问题的简单非递归解决方案。

let  object1 = { auth : "ok", response : { auth : "ok" }, check : { check1 : { check2 : {auth : "no"} } } };
let object2 = { auth : "ok", response : { auth : "ok" }, check : { check1 : { check2 : {auth : "ok"} } } };

function findAndValidateKey(object, targetKey, value){
  let res = true, found = false;
  let stack = [JSON.parse(JSON.stringify(object))];
  while(stack.length){
    let obj = stack.pop();
    for(var key in obj){
      if(obj.hasOwnProperty(key) && key === targetKey){
        res = res && (obj[key] === value);
        found = true;
        if(!res)
          break;
      } else if(obj[key] instanceof  Object && !Array.isArray(obj[key])){
        stack.push(obj[key]);
      }
    }
    if(!res)
      break;
  }
  res = res && found;
  return res;
}

console.log(findAndValidateKey(object1, "auth","ok"));
console.log(findAndValidateKey(object2, "auth","ok"));

答案 2 :(得分:0)

您可以做的是初始化array以获取属于同一values的所有key,然后最后检查所有这些{{1} }等于搜索到的array,使用:

value

这应该是您更新的let rs = matches.every(m => m == value);

function

演示:

let matches = [];
function findValue(obj, key) {
  if (obj.hasOwnProperty(key)) {
    matches.push(obj[key]);
  }
  for (k in obj) {
    if (Array.isArray(obj[k])) {
      obj[k].forEach(el => findValue(el, key));
    } else if (obj[k] && typeof obj[k] == "object") {
      findValue(obj[k], key);
    }
  }
}

答案 3 :(得分:0)

import React from "react";
import Checkbox from "./Checkbox";

export default ({ options, ...props }) => (
  <div
    className="ant-checkbox-group"
    style={{ display: "inline-block", marginRight: 10 }}
  >
    {options.map(label => (
      <Checkbox
        key={label}
        label={label}
        disabled={props.disabled}
        handleChange={props.handleChange}
        value={props[label]}
      />
    ))}
  </div>
);