是否可以在不知道父母的情况下访问对象的子节点?

时间:2014-06-23 18:14:15

标签: javascript arrays json

我有一个对象:

[
    {"ML":[
        {"TeamName":"Team 1","League":"League 1"},
        {"TeamName":"Team 2","League":"League 2"},
        {"TeamName":"Team 3","League":"League 3"}
    ]},
    {"3A":[
        {"TeamName":"Team 4","League":"League 1"},
        {"TeamName":"Team 5","League":"League 2"},
        {"TeamName":"Team 6","League":"League 3"}
    ]},
    {"2A":[
        {"TeamName":"Team 7","League":"League 1"},
        {"TeamName":"Team 8","League":"League 2"},
        {"TeamName":"Team 9","League":"League 3"}
    ]}
]

如何在不指定父级的情况下访问每个组的"TeamName"(例如"ML")?

通常情况下,ML.TeamName可以执行x.TeamnName之类的操作吗?

原因是组名是动态且不可预测的。

我基本上想要遍历组(父组在其中设置子组)。可以把它想象成为每个组创建一个<ul>(带有作为标题的组名称)和<li>中具有&#34; TeamName&#34;的值的子项列表。

我使用jQuery并想要这样的结果:

<h4>ML</h4>
<ul>
  <li>Team 1</li>
  <li>Team 2</li>
  <li>Team 3</li>
</ul>

<h4>3A</h4>
<ul>
  <li>Team 4</li>
  <li>Team 5</li>
  <li>Team 6</li>
</ul>

<h4>2A</h4>
<ul>
  <li>Team 7</li>
  <li>Team 8</li>
  <li>Team 9</li>
</ul>

4 个答案:

答案 0 :(得分:2)

如果您的对象存储在data中,则可以使用ES5 map

data.Result.map(function(obj){
    for(var i in obj) if(obj.hasOwnProperty(i))
        return obj[i].map(function(obj){
            return obj.TeamName
        });
});

或简化ES6 arrow functions

data.Result.map(obj => {
    for(var i in obj) if(obj.hasOwnProperty(i))
        return obj[i].map(obj => obj.TeamName);
});

通过少量修改,您可以获得这些HTML(注意它易受html注入)

wrapper.innerHTML += data.Result.map(obj => {
    for(var i in obj) if(obj.hasOwnProperty(i))
        return '<h4>'+i+'</h4>\n'
            + obj[i].map(obj => '\t<li>'+obj.TeamName+'</li>\n').join('');
}).join('');

这种方式并不容易受到攻击:

data.Result.forEach(obj => {
    for(var i in obj) if(obj.hasOwnProperty(i)) {
        var h4 = document.createElement('h4'),
            ul=document.createElement('ul');
        h4.appendChild(document.createTextNode(i));
        wrapper.appendChild(h4);
        obj[i].forEach(obj => {
            var li = document.createElement('li');
            li.appendChild(document.createTextNode(obj.TeamName));
            ul.appendChild(li);
        });
        wrapper.appendChild(ul);
        return;
    }
})

答案 1 :(得分:0)

使用括号表示法:

Result["ML"].TeamName

如果你想知道列表中的所有内容

var result = JSON.parse(...);

for (var i = 0; i < result.Result.length; i++) {
  console.log(result.Result[i])
}

答案 2 :(得分:0)

假设目标是消除额外级别并使团队变平,请考虑以下事项(fiddle)。它使用基本循环,但希望显示解构过程。

var results = json.Result;
var teams = [];
for (var i = 0; i < results.length; i++) {
   var conf = results[i];
   // conf will be like {ML: ..}
   for (var p in conf) {
       // Enumerate properties, p is "ML", etc. In the given JSON there
       // will only be one property to enumerate.
       if (conf.hasOwnProperty(p)) {               
           var confTeams = conf[p];
           // confTeams is like [{TeamName:..},..]
           teams = teams.concat(confTeams)
       }
   }
};

现在teams包含转换后的数据,如:

[ {"TeamName":"Team 1","League":"League 1"},
  {"TeamName":"Team 2","League":"League 2"},
  .. ]

答案 3 :(得分:0)

如果你使用像lodash或下划线

这样的库

如果您不需要知道原始密钥......

var list = _.reduce(j.Result,function(c,v,i,l){
  return c.concat(_.values(v)[0]);
},[])

如果要索引对象内的原始键...

var list = _.reduce(j.Result,function(c,v,i,l){
  return c.concat(_.map(_.values(v)[0],function(vv,ii){
    vv.key = _.keys(v)[0]
    return vv; // change each object here
  }));
},[]);

console.log(list)

JSBIN