【问题标题】:how to get construct object in specified manner from given object如何从给定对象以指定方式获取构造对象
【发布时间】:2018-08-23 09:40:40
【问题描述】:

我在以所需格式构造 object 时遇到问题。

我想以这种方式获取对象

{"pendrive":['went to each object and picked "TEST_HOME" value'],"minichip":['went to each object and picked "TEST_PROXY" value']}

上述array的值必须从每个object中收集,方法是转到mount_status然后key,对于示例 TEST_PROXY,TEST_HOME,TEST_ARCHIVE ,TEST_TARGET

所需的输出: {"pendrive":["error","na","error","ok","na","na"]} 用于键 "TEST_HOME" 其他人相同

这是我尝试过的:

  var nodeSum = {};
var nodeStatus = {
  "node_stats": {
    "pendrive": {
      "mount_status": {
        "TEST_PROXY": "error",
        "TEST_TARGET": "error",
        "TEST_ARCHIVE": "error",
        "TEST_HOME": "error"
      }
    },
    "minichip": {
      "mount_status": {
        "TEST_PROXY": "na",
        "TEST_TARGET": "na",
        "TEST_ARCHIVE": "na",
        "TEST_HOME": "na"
      }
    },
    "simcard": {
      "mount_status": {
        "TEST_HOME": "error",
        "TEST_TARGET": "error",
        "TEST_ARCHIVE": "error",
        "TEST_PROXY": "error"
      }
    },
    "hostname": [
      "nikola",
      "goldplus",
      "pendrive",
      "simcard",
      "airtel",
      "minichip",
      "voda"
    ],
    "airtel": {
      "mount_status": {
        "TEST_PROXY": "ok",
        "TEST_TARGET": "ok",
        "TEST_ARCHIVE": "ok",
        "TEST_HOME": "ok"
      }
    },
    "voda": {
      "mount_status": {
        "TEST_HOME": "na",
        "TEST_TARGET": "na",
        "TEST_ARCHIVE": "na",
        "TEST_PROXY": "na"
      }
    },
    "nikola": {
      "mount_status": {
        "TEST_HOME": "na",
        "TEST_ARCHIVE": "na",
        "TEST_TARGET": "na",
        "TEST_PROXY": "na"
      }
    }
  }
}


console.log(nodeStatus);

var hostNames = nodeStatus["node_stats"]["hostname"];

for(var i = 0; i<hostNames.length;i++){

  if(nodeStatus["node_stats"][hostNames[i]]){
    eachNode = nodeStatus["node_stats"][hostNames[i]];
    console.log(eachNode);
  }
  //nodeSum[hostNames[i]] = eachNode["mount_status"][Object.keys(eachNode["mount_status"])];
  if(eachNode){
    if(eachNode.hasOwnProperty("mount_status")){
      if(i <= 1)
        var allBins = Object.keys(eachNode["mount_status"]);
        console.log('all keys',allBins);
        console.log(nodeStatus["node_stats"][hostNames[i]][allBins[i]]);
        console.log(Object.values(eachNode["mount_status"]));

        var binStatusArray = Object.values(eachNode["mount_status"]);
        nodeSum[allBins[i]] = eachNode["mount_status"][allBins[i]];
      }
    }         
  }
  console.log('results',nodeSum);
}

【问题讨论】:

  • {"pendrive":["error","na","error","ok","na","na"]} 只有一个TEST_HOME 是它的孩子,你确定不想要node_stats 吗?
  • 你的缩进让这段代码很难阅读。

标签: javascript jquery node.js


【解决方案1】:

如果可能,我会更改以下内容

const nodeStatus = {
  "hostname": [
      "nikola",
      "goldplus",
      "pendrive",
      "simcard",
      "airtel",
      "minichip",
      "voda"
  ],
  "node_stats": {
    "pendrive": {
      "mount_status": {
        "TEST_PROXY": "error",
        "TEST_TARGET": "error",
        "TEST_ARCHIVE": "error",
        "TEST_HOME": "error"
      }
    },
    "minichip": {
      "mount_status": {
        "TEST_PROXY": "na",
        "TEST_TARGET": "na",
        "TEST_ARCHIVE": "na",
        "TEST_HOME": "na"
      }
    },
    "simcard": {
      "mount_status": {
        "TEST_HOME": "error",
        "TEST_TARGET": "error",
        "TEST_ARCHIVE": "error",
        "TEST_PROXY": "error"
      }
    },
    "airtel": {
      "mount_status": {
        "TEST_PROXY": "ok",
        "TEST_TARGET": "ok",
        "TEST_ARCHIVE": "ok",
        "TEST_HOME": "ok"
      }
    },
    "voda": {
      "mount_status": {
        "TEST_HOME": "na",
        "TEST_TARGET": "na",
        "TEST_ARCHIVE": "na",
        "TEST_PROXY": "na"
      }
    },
    "nikola": {
      "mount_status": {
        "TEST_HOME": "na",
        "TEST_ARCHIVE": "na",
        "TEST_TARGET": "na",
        "TEST_PROXY": "na"
      }
    }
  }
}

const testHome = nodeStatus.hostname.map(name => nodeStatus["node_stats"][name] 
  ? nodeStatus["node_stats"][name]["mount_status"]["TEST_HOME"] 
  : undefined);

// ["nikola", "goldplus", "pendrive", "simcard", "airtel", "minichip", "voda"]
console.log(testHome) //["na", undefined, "error", "error", "ok", "na", "na"]

主机名与所有其他主机名不同,因此您希望将其从node_stats 中取出。结果的顺序将与hostname的顺序相同

如果您不想要未定义的,那么您可以使用Array.reduce,但副作用是Array 的顺序无法预测。

【讨论】:

    【解决方案2】:

    您可以对每种类型的项目和属性名称使用对象查找。然后使用Object.keys()遍历lookup的每个key,array#reduce每个key对应lookup属性的所有值,并使用array#reduce每个对象的所有值创建一个数组。

    var nodeStatus = { "node_stats": { "pendrive": { "mount_status": { "TEST_PROXY": "error", "TEST_TARGET": "error", "TEST_ARCHIVE": "error", "TEST_HOME": "error" } }, "minichip": { "mount_status": { "TEST_PROXY": "na", "TEST_TARGET": "na", "TEST_ARCHIVE":"na", "TEST_HOME": "na" } }, "simcard": { "mount_status":{ "TEST_HOME": "error", "TEST_TARGET": "error", "TEST_ARCHIVE": "error", "TEST_PROXY": "error" } }, "hostname": [ "nikola", "goldplus", "pendrive", "simcard", "airtel", "minichip", "voda" ], "airtel":{ "mount_status": { "TEST_PROXY": "ok", "TEST_TARGET": "ok", "TEST_ARCHIVE": "ok", "TEST_HOME": "ok" } }, "voda": { "mount_status": { "TEST_HOME": "na", "TEST_TARGET": "na", "TEST_ARCHIVE": "na", "TEST_PROXY": "na" } }, "nikola": { "mount_status": { "TEST_HOME":"na", "TEST_ARCHIVE": "na", "TEST_TARGET": "na", "TEST_PROXY": "na" } } } },
        lookup = {pendrive: 'TEST_HOME', minichip: 'TEST_PROXY'}
        result = Object.keys(lookup).reduce((o,k) => {
          o[k] =  Object.keys(nodeStatus.node_stats).reduce((r,key) => {
          if('mount_status' in nodeStatus.node_stats[key])
              r.push(nodeStatus.node_stats[key].mount_status[lookup[k]]);
          return r;
        },[]);
        return o;
       },{});
    console.log(result);

    【讨论】:

      【解决方案3】:

      如果你想要这样的输出:

      TEST_ARCHIVE的键

      {error: ["pendrive", "simcard"], na: ["minichip", "voda", "nikola"], ok: ["airtel"]}
      

      使用这个:

      function getNestedValuesForKey(key_name){
      	var hosts	=	nodeStatus.node_stats;
      	var return_values	=	{};
      	for( var _hostname in hosts ){
      		var _host	=	hosts[_hostname];
      		if( _host.mount_status ){
      			var _status	=	_host.mount_status[key_name];
      			if( !return_values[_status] ){
      				return_values[_status]	=	new Array;
      			}//if
      			return_values[_status].push(_hostname);
      		}//if
      	}//for
      	return return_values
      }//function
      
      var nodeStatus = {"node_stats":{"pendrive":{"mount_status":{"TEST_PROXY":"error","TEST_TARGET":"error","TEST_ARCHIVE":"error","TEST_HOME":"error"}},"minichip":{"mount_status":{"TEST_PROXY":"na","TEST_TARGET":"na","TEST_ARCHIVE":"na","TEST_HOME":"na"}},"simcard":{"mount_status":{"TEST_HOME":"error","TEST_TARGET":"error","TEST_ARCHIVE":"error","TEST_PROXY":"error"}},"hostname":["nikola","goldplus","pendrive","simcard","airtel","minichip","voda"],"airtel":{"mount_status":{"TEST_PROXY":"ok","TEST_TARGET":"ok","TEST_ARCHIVE":"ok","TEST_HOME":"ok"}},"voda":{"mount_status":{"TEST_HOME":"na","TEST_TARGET":"na","TEST_ARCHIVE":"na","TEST_PROXY":"na"}},"nikola":{"mount_status":{"TEST_HOME":"na","TEST_ARCHIVE":"na","TEST_TARGET":"na","TEST_PROXY":"na"}}}};
      
      console.log( getNestedValuesForKey('TEST_ARCHIVE') );

      【讨论】:

        【解决方案4】:

        目前还不清楚你想要什么。一种可能性是,当您在寻找 TEST_PROXY 时,您应该得到

        ["na", undefined, "error", "error", "ok", "na", "na"]
        

        undefined 是因为hostname 包含“goldplus”,而node_stats 中不包含。)

        如果这是您想要的,那么这应该可以:

        const nodeStatus = {"node_stats": {"airtel": {"mount_status": {"TEST_ARCHIVE": "ok", "TEST_HOME": "ok", "TEST_PROXY": "ok", "TEST_TARGET": "ok"}}, "hostname": ["nikola", "goldplus", "pendrive", "simcard", "airtel", "minichip", "voda"], "minichip": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}, "nikola": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}, "pendrive": {"mount_status": {"TEST_ARCHIVE": "error", "TEST_HOME": "error", "TEST_PROXY": "error", "TEST_TARGET": "error"}}, "simcard": {"mount_status": {"TEST_ARCHIVE": "error", "TEST_HOME": "error", "TEST_PROXY": "error", "TEST_TARGET": "error"}}, "voda": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}}}
        
        const nodeSum = (key, nodes) => nodes.node_stats.hostname
            .map(hostname => (nodes.node_stats[hostname] || {mount_status: {}}).mount_status[key])
        
        
        console.log(nodeSum("TEST_PROXY", nodeStatus))

        但那是相当不清楚的格式。相反,如果你想要这样的东西:

        {
          "nikola":"na",
          "pendrive":"error",
          "simcard":"error",
          "airtel":"ok",
          "minichip":"na",
          "voda":"na"
        }
        

        然后你可以像这样修改函数:

        const nodeStatus = {"node_stats": {"airtel": {"mount_status": {"TEST_ARCHIVE": "ok", "TEST_HOME": "ok", "TEST_PROXY": "ok", "TEST_TARGET": "ok"}}, "hostname": ["nikola", "goldplus", "pendrive", "simcard", "airtel", "minichip", "voda"], "minichip": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}, "nikola": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}, "pendrive": {"mount_status": {"TEST_ARCHIVE": "error", "TEST_HOME": "error", "TEST_PROXY": "error", "TEST_TARGET": "error"}}, "simcard": {"mount_status": {"TEST_ARCHIVE": "error", "TEST_HOME": "error", "TEST_PROXY": "error", "TEST_TARGET": "error"}}, "voda": {"mount_status": {"TEST_ARCHIVE": "na", "TEST_HOME": "na", "TEST_PROXY": "na", "TEST_TARGET": "na"}}}}
        
        const nodeSum = (key, nodes) => nodes.node_stats.hostname
            .map(hostname => ({[hostname]: (nodes.node_stats[hostname] || {mount_status: {}})
                                           .mount_status[key]}))
            .reduce((a, b) => Object.assign(a, b), {})
        
        console.log(nodeSum("TEST_HOME", nodeStatus))

        如果您可以保证在您的示例中没有像“goldplus”这样的情况,其中主机名包含在主机名列表中但不包含在node_stats 中,那么您可以将这些函数简化为

        const nodeSum = (key, nodes) => nodes.node_stats.hostname
            .map(hostname => nodes.node_stats[hostname].mount_status[key])
        

        const nodeSum = (key, nodes) => nodes.node_stats.hostname
            .map(hostname => ({[hostname]: nodes.node_stats[hostname].mount_status[key]}))
            .reduce((a, b) => Object.assign(a, b), {})
        

        最后,在一次迭代中完成后者可能会更干净,如下所示:

        const nodeSum = (key, nodes) => nodes.node_stats.hostname
            .reduce((acc, hostname) => {
              acc[hostname] = nodes.node_stats[hostname].mount_status[key]
              return acc
            }, {})
        

        nodeSum 是这个函数的一个可怕 名称,但您似乎正在使用该名称更新一个变量来保存您的输出。对于实际代码,我会将其更改为更明确的内容。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-31
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-05-24
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多