我有一个json数组
[{
id:1,
topicid : 1,
Topic:Topic_name,
categoryid:1,
category : category_name,
subcategoryid:1,
subcategory : subcategory_name,
pageid: 1,
pageurl : pageurl_name
}]
我想将json转换为下面的结构,你能不能请任何人使用jquery或JavaScript来帮助我。
[{
id :1
topicid:tiopicid,
text: "topic_name",
items: [{
categoryid:categoryid,
text: "category_name" ,
items: [{
subcategoryid:subcategoryid
text: "subcategory_name" ,
items: [{
pageid:pageid,
text: "pageurl_name"
}]
}]
}]
}]
答案 0 :(得分:0)
看起来您对(粗略地)规范化数据集感兴趣。在这种情况下,分组是任务。我清理了一些字段名称,以便更加一致和方便地使用这个特定的解决方案。
请注意,不会阻止数据在不同的子组中重复。同样,如果原始数据跨不同主题复制<input type="text" id="qty_req_<?php echo $i; ?>" data-oldvalue="<?php echo $req; ?>" />
<script>
$( document ).ready(function() {
oldvalue = $("#qty_req_<?php echo $i; ?>").data('oldvalue');
});
</script>
,则两者都将写入每个主题(没有数据库连接或简单JSON中的引用)。这对您来说可能是也可能不是问题。
我使用了Ramda.js,这是一个功能强大的Javascript库。这也可以使用lodash,下划线甚至直接JS来完成。 jQuery不会帮助你;它主要是一个DOM兼容库。在代码之前的最后一个想法:使用循环执行此操作是完全可能的,但循环突变很棘手,尤其是这么多级别。
任务是获取一组对象,每个对象具有相同的字段,并逐步将它们分组到容器对象中。每个对象包含原始id,id的名称和pageid
个子对象的列表(最后一个id缺少此项目列表)id桶是:
items
因此,对于每个id,数据必须是:
var ids = ['topic', 'category', 'subcategory', 'page'];
中,并根据剩余的ID再次进行分组。以下是相关代码:
items
(groupIdList, currentDataSet) => {
var currentId = R.head(groupIdList);
var remainingIds = R.tail(groupIdList);
var groupedByCurrentId = R.pipe(
R.groupBy(R.prop(currentId + 'id')),
R.map((lst) => {
// by definition, all elements in the list
// will have the same id (and barring bad initial data,
// the same root value) So the guaranteed exisiting first
// element is used as a template
var first = R.head(lst);
// if ids remain, populate the items field
var obj = remainingIds.length > 0 ? {
items: groupBy(remainingIds, lst)
} : {};
obj[currentId + 'id'] = first[currentId + 'id'];
obj[currentId] = first[currentId];
return obj;
}),
// groupBy returns an object key/values, and map perserves this.
// but this function only cares about the values at this point
R.values
)(currentDataSet);
return groupedByCurrentId;
};
/* jshint esnext: true */
var rawJson = [{
"id": 1,
"topicid": 1,
"topic": "topic1",
"categoryid": 1,
"category": "cat1",
"subcategoryid": 1,
"subcategory": "subcat1",
"pageid": 1,
"page": "pageurl1"
}, {
"id": 2,
"topicid": 1,
"topic": "topic1",
"categoryid": 1,
"category": "cat1",
"subcategoryid": 2,
"subcategory": "subcat2",
"pageid": 1,
"page": "pageurl1"
}, {
"id": 4,
"topicid": 1,
"topic": "topic1",
"categoryid": 1,
"category": "cat1",
"subcategoryid": 2,
"subcategory": "subcat2",
"pageid": 5,
"page": "pageurl5"
}, {
"id": 3,
"topicid": 2,
"topic": "topic2",
"categoryid": 4,
"category": "cat4",
"subcategoryid": 6,
"subcategory": "subcat6",
"pageid": 10,
"page": "pageurl10"
}];
var groupBy = (groupIdList, currentDataSet) => {
var currentId = R.head(groupIdList);
var remainingIds = R.tail(groupIdList);
var groupedByCurrentId = R.pipe(
R.groupBy(R.prop(currentId + 'id')),
R.map((lst) => {
// by definition, all elements in the list
// will have the same id (and barring bad initial data,
// the same root value) So the guaranteed exisiting first
// element is used as a template
var first = R.head(lst);
// if ids remain, populate the items field
var obj = remainingIds.length > 0 ? {
items: groupBy(remainingIds, lst)
} : {};
obj[currentId + 'id'] = first[currentId + 'id'];
obj[currentId] = first[currentId];
return obj;
}),
// groupBy returns an object key/values, and map perserves this.
// but this function only cares about the values at this point
R.values
)(currentDataSet);
return groupedByCurrentId;
};
var ids = ['topic', 'category', 'subcategory', 'page'];
var output = groupBy(ids, rawJson);
console.log(output);
document.getElementById('results').innerText = JSON.stringify(output, null, 2);