javascript - 如何从 JavaScript 数据结构生成 HTML 列表结构?

标签 javascript list object recursion traversal

我需要遍历这个数据结构来呈现一组列表。对于嵌套数据与父级具有相同结构的结构,这不会有问题 - 但这里所有模型都是不同的。将有一个列表,其中每个项目都包含此结构中每个级别的列表。就像这样:

期望结果:

未选择

| Countries | Provinces | Cities      | <--- Top ul
---------------------------------------
|-China     |           |             | <--- Sub uls
|-Denmark   |           |             |

已选择

| Countries | Provinces | Cities      |
---------------------------------------
|-China   X |-Matjii X  |- Go Neng    |
|-Denmark   |-Pausiu    |- Tsau Pei X |

X 代表选定的选项。如果选择了某个项目,则后续列表中应只显示该项目的信息。如上所示,由于选择了中国,因此以下列表中没有显示来自丹麦的数据。

数据结构:

{
  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)。

在这个回复中,我假设您别无选择,只能从前端进行。

每个国家/地区对其地理位置都有不同的命名约定,例如。有的称其为市、县、镇、村等。

尽管命名有所不同,但它们都遵循树状层次结构。因此,这就是你的攻击 Angular 。根据层次级别对它们进行标准化。

以下示例代码将以层次结构级别打印出示例数据。它们的水平通过压痕量进行对比。复制并粘贴以下代码并在浏览器控制台中运行它。

数据:

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);

预期输出:

enter image description here

希望这能为您提供解决问题的替代方案

关于javascript - 如何从 JavaScript 数据结构生成 HTML 列表结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51950635/

相关文章:

javascript - 以一对多关系将对象组合在一起

java - 创建接受接口(interface)对象数组的方法

javascript - 单击菜单项时,更改正文样式

list - 动态规划中包含前缀和吗?

javascript - 如何使用 JS 从其类中选择特定的 Div

java - 为什么数组被初始化为默认值而不是 java 中的 arraylist?

python - 打印两个列表中的值对

java - 引用自身的类如何工作?

javascript - 为什么不推荐使用 String.prototype.substr()?

javascript - 如何为服务 worker 缓存音频文件?