遍历Javascript对象以构建嵌套列表

时间:2018-07-13 18:41:31

标签: javascript jquery

我正在尝试使用递归循环从这样的结构的对象构建HTML列表-可能深度的级别是无限的:

100 - 200

循环应创建一个嵌套的html列表,如下所示:

object = {
   "directories":{
      "vegetables":{
         "info":{
            "name":"Vegetables"
         },
         "files":{

         },
         "directories":{
            "green vegetables":{
               "info":{
                  "name":"Green Vegetables"
               },
               "files":{

               },
               "directories":{
                  "lettuce":{
                     "info":{
                        "name":"Lettuce"
                     },
                     "files":{

                     }
                  },
                  "cucumber":{
                     "info":{
                        "name":"Cucumber"
                     },
                     "files":{

                     }
                  }
               }
            },
            "orange vegetables":{
               "info":{
                  "name":"Orange Vegetables"
               },
               "files":{

               },
               "directories":{
                  "3 deep":{
                     "info":{
                        "name":"Carrot"
                     },
                     "files":{

                     }
                  }
               }
            }
         }
      },
      "fruit":{
         "info":{
            "name":"Fruit"
         },
         "files":{

         },
         "directories":{
            "apple":{
               "info":{
                  "name":"Apple"
               },
               "files":{

               }
            }
         }
      }
   }
}

当前我的函数看起来像这样,但是目前它在第一个列表项之后卡住了,我正在努力寻找如何正确递归调用自己的方法:

<ul>
    <li>Vegetables
        <ul>
            <li>Green Vegetables
                <ul>
                    <li>Lettuce</li>
                    <li>Cucumber</li>
                </ul>
            </li>
            <li>Orange Vegetables
                <ul>
                    <li>Carrot</li>
                </ul>
            </li>
        </ul>
    </li>
    <li>Fruit
        <ul>
            <li>Apple</li>
        </ul>
    </li>
</ul>

如何重写函数以与Javascript对象一起使用?

2 个答案:

答案 0 :(得分:1)

您可以采用递归方法,方法是采用目录对象,并使用名称作为值构建一个新的<ul>列表,并检查嵌套的目录属性。

function getList(directories) {
    return Object
        .values(directories)
        .reduce((ul, { info: { name }, directories }) => {
            var li = document.createElement('li');
            li.appendChild(document.createTextNode(name));
            ul.appendChild(li);
            if (directories) {
                li.appendChild(getList(directories));
            }
            return ul;
        }, document.createElement('ul'));
}

var data = { directories: { vegetables: { info: { name: "Vegetables" }, files: {}, directories: { "green vegetables": { info: { name: "Green Vegetables" }, files: {}, directories: { lettuce: { info: { name: "Lettuce" }, files: {} }, cucumber: { info: { name: "Cucumber" }, files: {} } } }, "orange vegetables": { info: { name: "Orange Vegetables" }, files: {}, directories: { "3 deep": { info: { name: "Carrot" }, files: {} } } } } }, fruit: { info: { name: "Fruit" }, files: {}, directories: { apple: { info: { name: "Apple" }, files: {} } } } } };

document.body.appendChild(getList(data.directories));
.as-console-wrapper { max-height: 100% !important; top: 0; }

答案 1 :(得分:0)

这可以通过香草JS轻松实现。见下文。

const data = {
   "directories":{
      "vegetables":{
         "info":{
            "name":"Vegetables"
         },
         "files":{

         },
         "directories":{
            "green vegetables":{
               "info":{
                  "name":"Green Vegetables"
               },
               "files":{

               },
               "directories":{
                  "lettuce":{
                     "info":{
                        "name":"Lettuce"
                     },
                     "files":{

                     }
                  },
                  "cucumber":{
                     "info":{
                        "name":"Cucumber"
                     },
                     "files":{

                     }
                  }
               }
            },
            "orange vegetables":{
               "info":{
                  "name":"Orange Vegetables"
               },
               "files":{

               },
               "directories":{
                  "3 deep":{
                     "info":{
                        "name":"Carrot"
                     },
                     "files":{

                     }
                  }
               }
            }
         }
      },
      "fruit":{
         "info":{
            "name":"Fruit"
         },
         "files":{

         },
         "directories":{
            "apple":{
               "info":{
                  "name":"Apple"
               },
               "files":{

               }
            }
         }
      }
   }
}

function buildList(dataRoot, elementRoot) {

  // Only continue if there are directories to look at
  if (dataRoot.directories) {
  
    // Create a new list and append it to our current element
    const list = document.createElement('ul');
    elementRoot.appendChild(list);
    Object.keys(dataRoot.directories).forEach(key => {
    
      // Get the directory from the key
      const directory = dataRoot.directories[key];
      
      // Create a text node and a list element to put it in
      const listElement = document.createElement('li');
      const textNode = document.createTextNode(directory.info.name);
      listElement.appendChild(textNode);
      list.appendChild(listElement);
      
      // Continue recursively down now using the current lis element
      buildList(directory, listElement);
    });
  }
}

const rootElement = document.getElementById("root");
buildList(data, rootElement);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="root"></div>