从JSON响应中解析一个不断更改顺序的值

时间:2016-12-31 11:40:27

标签: javascript json tasker

我试图在javscript中解析来自家庭自动化系统的JSON响应。 回应是  available here

这只是响应的一小部分,而且,由于我不知道的原因,每次重启时键的顺序都会发生变化,su使用数字索引不会真正起作用 我需要能够将sensor.out,sensor.in,sensor.door的状态值存储到andorid上的tasker的变量中 我试图选择使用entity.id,但由于某种原因代码永远不会完成(我相信我只是不知道我在做什么)

3 个答案:

答案 0 :(得分:1)

使用ES6,您可以使用Array#find方法:

response.find(o => o.entity_id == 'sensor.out').state

请参阅代码段:



var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
var state = response.find(o => o.entity_id == 'sensor.out').state;
console.log('sensor.out state is', state);




或者,您可以将响应转换为具有实体ID值作为键的对象,因此您可以像response['session.out'].state一样访问它:

response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));

请参阅代码段:



var response = [ { "attributes":{ "friendly_name":"door" }, "entity_id":"sensor.door", "last_changed":"2016-12-31T11:15:59.395808+00:00", "last_updated":"2016-12-31T11:15:59.395808+00:00", "state":"closed" }, { "attributes":{ "friendly_name":"In", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.in", "last_changed":"2016-12-31T11:20:02.179821+00:00", "last_updated":"2016-12-31T11:20:02.179821+00:00", "state":"20.7" }, { "attributes":{ "changed_by":null, "code_format":".+", "friendly_name":"panel" }, "entity_id":"alarm_control_panel.panel", "last_changed":"2016-12-31T11:14:56.471966+00:00", "last_updated":"2016-12-31T11:14:56.471966+00:00", "state":"disarmed" }, { "attributes":{ "friendly_name":"Out", "unit_of_measurement":"\u00b0C" }, "entity_id":"sensor.out", "last_changed":"2016-12-31T11:14:58.452345+00:00", "last_updated":"2016-12-31T11:14:58.452345+00:00", "state":"7.1" }];
response = Object.assign({}, ...response.map( o => ({[o.entity_id]: o}) ));
console.log('sensor.out state is', response['sensor.out'].state);




答案 1 :(得分:0)

如果您尝试使用索引从对象中选择属性,则不应该这样做,除非有非常具体的理由这样做。

幸运的是,没关系,你不需要知道订单。我从JSON数组中获取了两个对象,对属性进行了加扰,并编写了一个函数,该函数返回包含您指定的键/值的任何对象。

你的问题有点难以理解,但我认为这会给你一个想法。

<script type="text/javascript">
let arr = [
  {
    "attributes":{
      "friendly_name":"door"
    },
    "entity_id":"sensor.frontdoor",
    "last_changed":"2016-12-31T11:15:59.395808+00:00",
    "last_updated":"2016-12-31T11:15:59.395808+00:00",
    "state":"closed"
  },
  {
    "last_changed":"2016-12-31T11:15:59.395808+00:00",
    "state":"closed",
    "attributes":{
      "friendly_name":"door"
    },
    "entity_id":"sensor.backdoor",
    "last_updated":"2016-12-31T11:15:59.395808+00:00"
  }
];

function findKey ( theKey, theVal ) {
  let reduced = arr.filter ( d => {
    return d [ theKey ] === theVal;
  });

  return reduced;
}

let targets = findKey ( 'entity_id', 'sensor.backdoor' );
targets.forEach ( d => {
   // This check is a little naive, but should give you the idea
   if ( 'state' in d ) {
      console.log ( d.state );
   }
} );
</script>

答案 2 :(得分:0)

每个人都说的是正确的:响应中键的顺序并不重要。使用(字符串)键,而不是数字索引。

var arr = [
  {
    "entity_id":"sensor.door",
    "state":"closed"
  }];   // other attributes chopped out for brevity

var entity_id_interested_in = 'sensor.door';
var state = '[entity_id not found in response]';
for (var i = 0; i < arr.length; i++) {

    console.log(arr[i].entity_id + ' state:' + arr[i].state);
    if (arr[i].entity_id == entity_id_interested_in)
    {
       state = arr[i].state;
       break;
    }
}
console.log (state);