如何从 JavaScript 数据结构生成 HTML 列表结构?
How can I produce an HTML list structure from JavaScript data structure?
我需要遍历这个数据结构来呈现一组列表。对于嵌套数据与父级结构相同的结构,这没有问题 - 但这里所有模型都不同。将有一个列表,其中每个项目包含此结构中每个级别的列表。像这样:
想要的结果:
未选择
| Countries | Provinces | Cities | <--- Top ul
---------------------------------------
|-China | | | <--- Sub uls
|-Denmark | | |
已选择
| Countries | Provinces | Cities |
---------------------------------------
|-China X |-Matjii X |- Go Neng |
|-Denmark |-Pausiu |- Tsau Pei X |
X
代表一个选择的选项。如果选择了一个项目,则只有它的信息应该显示在后续列表中。正如您在上面看到的,由于选择了 China
,因此以下列表没有显示来自 Denmark
的数据。
数据结构:
{
countries: {
china: {
name: "China",
provinces: {
matjii: {
name: "Matjii",
cities: {
goneng: {
name: "Go Neng"
},
tsauPei: {
name: "Tsau Pei"
}
}
},
pausiu: {
name: "Pausiu",
cities: {...}
}
}
},
denmark: {
name: "Denmark",
counties: {
borjskada: {
name: "Borjskada",
towns: {
fjollmaska: {
name: "Fjollmaska"
}
}
},
larvmauda: {
name: "Larvmauda",
towns: {
tarnaby: {
name: "Taernaby"
}
}
}
}
}
}
}
我尝试过两种不同的递归方法,但让我停滞不前的是,我总是无法预料下一个级别可能被称为什么(城市、城镇或 matjii)。
我是否遗漏了一些简单明显的解决方案?伪代码很好,我正在寻找一个通用的方法。
基本上,我认为关键在于从后端或前端 (js) 规范化数据。
在此回复中,我假设您别无选择,只能从前端进行。
每个国家/地区对其地理位置都有不同的命名约定,例如。有人将其命名为市、县、镇、村等。
尽管命名不同,但它们都遵循树状层次结构。因此,这是您的攻角。根据层级对它们进行规范化。
以下示例代码将按层次打印出您的示例数据。它们的水平与缩进量形成对比。复制并粘贴以下代码,然后 运行 将其粘贴到您的浏览器控制台中。
数据:
var data = {
countries: {
china: {
name: "China",
provinces: {
matjii: {
name: "Matjii",
cities: {
goneng: {
name: "Go Neng"
},
tsauPei: {
name: "Tsau Pei"
}
}
},
pausiu: {
name: "Pausiu",
}
}
},
denmark: {
name: "Denmark",
counties: {
borjskada: {
name: "Borjskada",
towns: {
fjollmaska: {
name: "Fjollmaska"
}
}
},
larvmauda: {
name: "Larvmauda",
towns: {
tarnaby: {
name: "Taernaby"
}
}
}
}
}
}
}
函数:
function traverseDataStructure(rootNode, nodeLevel){
if(!rootNode) return;
if(nodeLevel > 3) return; //just a secondary protection for infinite recursion
if(!nodeLevel)
nodeLevel = 0;
var indentationForPrinting = '';
for(var i=0;i<nodeLevel;i++){
indentationForPrinting += ' ';
}
console.log(indentationForPrinting + 'Traversing level ' + nodeLevel);
for(var prop in rootNode){
//prop may either by countries (level 0) or provinces (level 1) or counties (level 1) or cities (level 2) or towns (level 2)
var regionType = prop;
var regionList = getRegionList(rootNode[prop]);
console.log(indentationForPrinting + 'regionType: ' + regionType);
console.log(indentationForPrinting + 'regionList: ' + regionList);
if(regionList.length <= 0) return;
//then iterate the list of regions
for(var i=0;i<regionList.length; i++){
for(var subRegion in regionList[i]){
if (subRegion == 'name'){
var regionName = regionList[i][subRegion];
console.log(indentationForPrinting + 'regionName: ' + regionName);
} else {
traverseDataStructure({subRegion: regionList[i][subRegion]}, nodeLevel+1);
}
}
}
}
}
function getRegionList(obj){
var list = [];
for(var location in obj){
list.push(obj[location]);
}
return list;
}
运行它:
traverseDataStructure(data);
预期输出:
希望这可以为您提供解决问题的替代方法
我需要遍历这个数据结构来呈现一组列表。对于嵌套数据与父级结构相同的结构,这没有问题 - 但这里所有模型都不同。将有一个列表,其中每个项目包含此结构中每个级别的列表。像这样:
想要的结果:
未选择
| Countries | Provinces | Cities | <--- Top ul
---------------------------------------
|-China | | | <--- Sub uls
|-Denmark | | |
已选择
| Countries | Provinces | Cities |
---------------------------------------
|-China X |-Matjii X |- Go Neng |
|-Denmark |-Pausiu |- Tsau Pei X |
X
代表一个选择的选项。如果选择了一个项目,则只有它的信息应该显示在后续列表中。正如您在上面看到的,由于选择了 China
,因此以下列表没有显示来自 Denmark
的数据。
数据结构:
{
countries: {
china: {
name: "China",
provinces: {
matjii: {
name: "Matjii",
cities: {
goneng: {
name: "Go Neng"
},
tsauPei: {
name: "Tsau Pei"
}
}
},
pausiu: {
name: "Pausiu",
cities: {...}
}
}
},
denmark: {
name: "Denmark",
counties: {
borjskada: {
name: "Borjskada",
towns: {
fjollmaska: {
name: "Fjollmaska"
}
}
},
larvmauda: {
name: "Larvmauda",
towns: {
tarnaby: {
name: "Taernaby"
}
}
}
}
}
}
}
我尝试过两种不同的递归方法,但让我停滞不前的是,我总是无法预料下一个级别可能被称为什么(城市、城镇或 matjii)。
我是否遗漏了一些简单明显的解决方案?伪代码很好,我正在寻找一个通用的方法。
基本上,我认为关键在于从后端或前端 (js) 规范化数据。
在此回复中,我假设您别无选择,只能从前端进行。
每个国家/地区对其地理位置都有不同的命名约定,例如。有人将其命名为市、县、镇、村等。
尽管命名不同,但它们都遵循树状层次结构。因此,这是您的攻角。根据层级对它们进行规范化。
以下示例代码将按层次打印出您的示例数据。它们的水平与缩进量形成对比。复制并粘贴以下代码,然后 运行 将其粘贴到您的浏览器控制台中。
数据:
var data = {
countries: {
china: {
name: "China",
provinces: {
matjii: {
name: "Matjii",
cities: {
goneng: {
name: "Go Neng"
},
tsauPei: {
name: "Tsau Pei"
}
}
},
pausiu: {
name: "Pausiu",
}
}
},
denmark: {
name: "Denmark",
counties: {
borjskada: {
name: "Borjskada",
towns: {
fjollmaska: {
name: "Fjollmaska"
}
}
},
larvmauda: {
name: "Larvmauda",
towns: {
tarnaby: {
name: "Taernaby"
}
}
}
}
}
}
}
函数:
function traverseDataStructure(rootNode, nodeLevel){
if(!rootNode) return;
if(nodeLevel > 3) return; //just a secondary protection for infinite recursion
if(!nodeLevel)
nodeLevel = 0;
var indentationForPrinting = '';
for(var i=0;i<nodeLevel;i++){
indentationForPrinting += ' ';
}
console.log(indentationForPrinting + 'Traversing level ' + nodeLevel);
for(var prop in rootNode){
//prop may either by countries (level 0) or provinces (level 1) or counties (level 1) or cities (level 2) or towns (level 2)
var regionType = prop;
var regionList = getRegionList(rootNode[prop]);
console.log(indentationForPrinting + 'regionType: ' + regionType);
console.log(indentationForPrinting + 'regionList: ' + regionList);
if(regionList.length <= 0) return;
//then iterate the list of regions
for(var i=0;i<regionList.length; i++){
for(var subRegion in regionList[i]){
if (subRegion == 'name'){
var regionName = regionList[i][subRegion];
console.log(indentationForPrinting + 'regionName: ' + regionName);
} else {
traverseDataStructure({subRegion: regionList[i][subRegion]}, nodeLevel+1);
}
}
}
}
}
function getRegionList(obj){
var list = [];
for(var location in obj){
list.push(obj[location]);
}
return list;
}
运行它:
traverseDataStructure(data);
预期输出:
希望这可以为您提供解决问题的替代方法