#javascript #arrays #json
#javascript #массивы #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>
котором есть значение «Имя_команды».
Я использую 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>
Комментарии:
1. Какой результат вы ищете? Набор имен команд или одно имя?
2. Конечно, но какой из них вы хотите, если скажете
x.TeamName
? ML, 3A или 2A? Есть причина, по которой у них есть ключевые значения… таким образом, вы знаете, о каком из них идет речь. Конечно, вы всегда можете перебрать их, а затем что-то сделать с каждым из них.3. Вы могли бы получить все родительские элементы и перебирать их…
4. В основном я хочу перебирать группы (родительские группы с дочерними элементами, установленными внутри них). Подумайте об этом как о создании
<ul>
для каждой группы (с именем группы в качестве заголовка) и списка дочерних элементов, в<li>
которых имеет значение"TeamName"
.5. @DrCord не могли бы вы подсказать мне, как это сделать?
Ответ №1:
Если ваш объект хранится в 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:
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. Потрясающе, большое вам спасибо! Я должен заглянуть в ES5 / ES6, выглядит интересно.
result
на самом деле это массив объектов, как мне его сохранитьdata
? Есть ли способ решить, куда будет введен html (например, добавление jQuery)? Допустим, я хочу добавить его<div class="content"></div>
.2. @Steve Если вы хотите заменить
data
, вы можете просто использоватьdata = data.Result.map(/* ... */)
. HTML будет введен вwrapper
.3. моя проблема заключалась в том, что у меня были данные в массиве объектов, таких как:
console.log(results)
shows[obj1, obj2, obj3]
, и при использовании вашего кода я получаюUncaught SyntaxError: Unexpected token >
при использованииresults.forEach(...
я обновил свой вопрос выше.4. @Steve Это может быть связано с тем, что ваш браузер не поддерживает функции ES6 arrow (к сожалению, в настоящее время его поддерживает только Firefox). Попробуйте заменить
obj => {
наfunction(obj){
.5. пошел с другим решением, но ваш код выглядит так, как будто это правильный ответ для браузера, поддерживающего ES6. Спасибо! 🙂
Ответ №2:
Используйте обозначение в скобках:
Result["ML"].TeamName
Если вы хотите знать все, что есть в списке
var result = JSON.parse(...);
for (var i = 0; i < result.Result.length; i ) {
console.log(result.Result[i])
}
Ответ №3:
Предполагая, что цель состоит в том, чтобы устранить дополнительный уровень и выровнять команды, рассмотрите следующее (скрипка). Он использует базовое зацикливание, но, надеюсь, показывает процесс деконструкции.
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"},
.. ]
Комментарии:
1. спасибо за ваш ответ, но на самом деле они все еще нужны мне в группе. Я добавил дополнительные детали к своему вопросу для уточнения.
2. @Steve, если они все еще нужны в группе, см. Ответ Ориоля и / или просто выполните обработку как есть (например, измените циклы выше, чтобы немедленно обработать значение, не возвращая сплющенную форму).
3. будет сделано. Еще раз спасибо за вашу помощь. 🙂
Ответ №4:
Если вы используете библиотеку, такую как 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)