以特定方式重新排列JSON数据



我有一个类似于下面的JSON数据集:

[
{
"name": "Concert 1",
"sponsors": [
{
"name": "Woolworths",
"location": "Mildura"
},
{
"name": "Coles",
"location": "Melbourne"
},
{
"name": "Metricon",
"location": "Wagga Wagga"
}
]
},
{
"name": "Concert 2",
"sponsors": [
{
"name": "Metricon",
"location": "Albert Park"
},
{
"name": "Woolworths",
"location": "Melbourne"
},
{
"name": "ALDI",
"location": "Bendigo"
}
]
},
{
"name": "Concert 3",
"sponsors": [
{
"name": "Holcim",
"location": "Bendigo"
},
{
"name": "Westpac",
"location": "Melbourne"
},
{
"name": "Coles",
"location": "Mildura"
}
]
}
]

我想在网页上以以下格式显示这个JSON输出:

Location X
Sponsor X
Concert 1
Concert 2
-------
Sponsor Y
Concert 1
Location Y
Sponsor Y
Concert 1
Concert 2
------
--------

基本上,我必须在顶层显示Location,并将其他元素显示为子元素,换句话说,将JSON数据集颠倒过来。

到目前为止,我已经尝试过使用VueJS计算的属性在JSON文件中循环,但仍然没有成功。有人能告诉我如何解决这个问题吗?

如果我没有在这里使用正确的技术术语,我很抱歉,因为我不确定当我们显示这样的东西时,我们该怎么称呼。

一个简单的解决方案是:

  • 将json数据传递到数据对象中的vue

  • 添加一个计算属性"formattedData",并提供一个函数,以您需要的格式格式化json数据。

  • 在模板中使用此计算属性来渲染数据

我会大致介绍一下你能做什么:

var concertData = [
{
"name": "Concert 1",
"sponsors": [
{
"name": "Woolworths",
"location": "Mildura"
},
{
"name": "Coles",
"location": "Melbourne"
},
{
"name": "Metricon",
"location": "Wagga Wagga"
}
]
},
{
"name": "Concert 2",
"sponsors": [
{
"name": "Metricon",
"location": "Albert Park"
},
{
"name": "Woolworths",
"location": "Melbourne"
},
{
"name": "ALDI",
"location": "Bendigo"
}
]
},
{
"name": "Concert 3",
"sponsors": [
{
"name": "Holcim",
"location": "Bendigo"
},
{
"name": "Westpac",
"location": "Melbourne"
},
{
"name": "Coles",
"location": "Mildura"
}
]
}
];
new Vue({
data: {
concerts: concertData // pass your concert json here
},
computed: {
formattedData: function () {
var formattedData = new Map();
this.concerts.forEach(function (item) {
item.sponsors.forEach(function (sponsor) {
if (!formattedData.has(sponsor.location)) {
formattedData.set(sponsor.location, new Map());
}
if (!formattedData.get(sponsor.location).has(sponsor.name)) {
formattedData.get(sponsor.location).set(sponsor.name, []);
}
formattedData.get(sponsor.location).get(sponsor.name).push(item.name);
})
});
return formattedData;
}
},
render: function(h) {
// loop over this.formattedData to paint the display
}
}).$mount("#app");

以下是如何转换数据:

const data = [{
"name": "Concert 1",
"sponsors": [
{"name": "Woolworths","location": "Melbourne"},
{"name": "Coles","location": "Melbourne"},
{"name": "Metricon","location": "Wagga Wagga"}
]
},
{
"name": "Concert 2",
"sponsors": [
{"name": "Metricon","location": "Albert Park"},
{"name": "Woolworths","location": "Melbourne"},
{"name": "ALDI","location": "Bendigo"}
]
},
{
"name": "Concert 3",
"sponsors": [
{"name": "Holcim","location": "Bendigo"},
{"name": "Westpac","location": "Melbourne"},
{"name": "Coles","location": "Mildura"}
]
}
];
const byLocation = data.reduce((r, con) => (con.sponsors.forEach(sp => {
if (!r[sp.location]) r[sp.location] = {};
if (!r[sp.location][sp.name]) r[sp.location][sp.name] = [];
r[sp.location][sp.name].push(con.name);
}), r), {});
console.log(byLocation);

解释以上内容:

转换音乐会的初始data阵列

[
concert,
concert,
// ...
]

到对象-其中所有属性名称(位置(都是唯一的

{
"location name 1": {},
"location name 2": {},
// ...
}

第一个想法是使用Array.prototype.reduce()MDN:

const byLocation = data.reduce((resultObject, concert) => {
// Insert concert data into resultObject here
return resultObject; // Return the Object for the next iteration
}, {}); // << {} is the resultObject

为简短起见,需要进行一些重命名,通过使用箭头函数的隐式返回(无换行大括号(,我们可以将以上内容转换/缩短为:

const byLocation = data.reduce((r, con) => (/*Insert con data into r*/, r), {});

所以con是迭代Concert,r是我们需要构建的最终结果对象
让我们通过forEach填充r对象,使用con.sponsors阵列

con.sponsors.forEach(sp => { // sp is the iterating Sponsor
// If r["location name"] does not exists, create it as empty object
if (!r[sp.location]) r[sp.location] = {};
// If r["location name"]["Sponsor name"] does not exists, create it
// as an empty array
if (!r[sp.location][sp.name]) r[sp.location][sp.name] = [];
// Finally push the Concert name into that array.
r[sp.location][sp.name].push(con.name);
})

如果概念过于高级,也可以这样写:

const data = [{
"name": "Concert 1",
"sponsors": [
{"name": "Woolworths","location": "Melbourne"},
{"name": "Coles","location": "Melbourne"},
{"name": "Metricon","location": "Wagga Wagga"}
]
},
{
"name": "Concert 2",
"sponsors": [
{"name": "Metricon","location": "Albert Park"},
{"name": "Woolworths","location": "Melbourne"},
{"name": "ALDI","location": "Bendigo"}
]
},
{
"name": "Concert 3",
"sponsors": [
{"name": "Holcim","location": "Bendigo"},
{"name": "Westpac","location": "Melbourne"},
{"name": "Coles","location": "Mildura"}
]
}
];
const byLocation = {}; // The resulting object of unique Locations
data.forEach((concert) => {
const sponsors = concert.sponsors;

sponsors.forEach((sponsor) => {

if (!byLocation.hasOwnProperty(sponsor.location)) {
byLocation[sponsor.location] = {};
}

if (!byLocation[sponsor.location].hasOwnProperty(sponsor.name)) {
byLocation[sponsor.location][sponsor.name] = [];
}

byLocation[sponsor.location][sponsor.name].push(concert.name);
});

});
console.log(byLocation);


以JavaScript显示<ul id="list"></ul>内部的数据:

const html = Object.entries(byLocation).reduce((h, [location, ob]) => {
h += `<li>${location}<ul>`;
Object.entries(ob).forEach(([sponsor, concerts]) => {
h += `<li>${sponsor}
<ul>
<li>${concerts.join('</li><li>')}</li>
</ul>
</li>`;
}); 
h += `</ul></li>`;
return h
}, ''); 
document.querySelector('#list').insertAdjacentHTML('beforeend', html);

最新更新