【问题标题】:Iterate through Multidimensional array in plain Javascript用纯 Javascript 遍历多维数组
【发布时间】:2018-12-02 07:40:29
【问题描述】:

我有以下 Json 文件,我正在尝试遍历所有内容,但是只有嵌套数组中的一项显示。不知道我在这里做错了什么。

JSON:

{
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },......

JS:

var d = document, 
        main = d.getElementsByTagName('nav')[ 0 ],
        ul = d.createElement( 'ul' ),
        i;

        main.appendChild( ul );

        axios.get('../data/colors.json')
        .then(function (response) {
            console.log(response.data.items);

            for( var i in response.data.items ){
                var li = d.createElement( 'li' ); 
                if(response.data.items[i].items.length){
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "<div>" + response.data.items[i].items[i].label + "</div>" + "</a>"; // create a new li element
                }
                else {
                    li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
                }
                ul.appendChild( li );// every time append a new item

            }

        })
        .catch(function (error) {
            console.log(error);
        });

期望的输出:

<ul>
<li>red<li>
<li>blue
  <div>green </div>
  <div>yellow </div>
  <div>pink</div>
</li>
</ul>

【问题讨论】:

  • for( var i in response.data.items ){ - 不要在数组上使用 for..in,使用常规的 for 循环 - for..in 用于迭代对象的属性。
  • 或者使用新的for ... of
  • 您要寻找的结果是什么?
  • 刚刚更新了想要的结果
  • @user992731 - 请尝试我的建议 - 常规的 for 循环将解决您的问题

标签: javascript json loops multidimensional-array


【解决方案1】:

你会想要迭代/循环嵌套的项目,而你没有这样做。基本上为第二级项目添加另一个循环。

这是一个清理后的版本:http://jsfiddle.net/DennisRas/zyn52p8v/
注意:我已删除 .axios 模块以显示重要内容。

const data = {
   "items":[
      {
         "label":"red",
         "url":"red",
         "items":[

         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      },
      {
         "label":"blue",
         "url":"#/blue",
         "items":[
            {
               "label":"green",
               "url":"#/green"
            },
            {
               "label":"yellow",
               "url":"#/yellow"
            },
            {
               "label":"pink",
               "url":"#/pink"
            }
         ]
      }
    ]
};

const nav = document.querySelector('nav');
const ul = document.createElement( 'ul' );

nav.appendChild(ul);

data.items.forEach(function(item) {
  const li = document.createElement('li');
  let html = "<a class='meta'>" + item.label;

  if (item.items && item.items.length) {
    item.items.forEach(function(subitem) {
        html += "<div>" + subitem.label + "</div>";
    });
  }

  html += "</a>";

  li.innerHTML = html;
  ul.appendChild(li);// every time append a new item
});

console.log(data.items);

【讨论】:

    【解决方案2】:

    你可以这样做 -

    var data = {
      "items": [{
          "label": "red",
          "url": "red",
          "items": [
    
          ]
        },
        {
          "label": "blue",
          "url": "#/blue",
          "items": [{
              "label": "green",
              "url": "#/green"
            },
            {
              "label": "yellow",
              "url": "#/yellow"
            },
            {
              "label": "pink",
              "url": "#/pink"
            }
          ]
        }
      ]
    }
    
    var createList = function(response) {
      var d = document,
        main = d.getElementById('list'),
        ul = d.createElement('ul'),
        i;
    
      main.appendChild(ul);
    
      //console.log(response.data.items);
    
      for (var i in response.data.items) {
        var li = d.createElement('li');
        if (response.data.items[i].items.length) {
          li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
          ul.appendChild(li); // every time append a new item
          var innerul = d.createElement('ul');
          for (var j in response.data.items[i].items) {
            var innerli = d.createElement('li');
            innerli.innerHTML = "<div>" + response.data.items[i].items[j].label + "</div>"; // create a new li element
            innerul.appendChild(innerli);
    
          }
          li = innerul;
        } else {
    
          li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "</a>"; // create a new li element
          ul.appendChild(li); // every time append a new item
        }
        ul.appendChild(li); // every time append a new item
      }
    
    }
    
    createList({
      data: data
    });
    &lt;div id="list"&gt;&lt;/div&gt;

    【讨论】:

    • 我遇到了重复问题
    • @user992731 我已经更新了答案以在有可用项目时创建子列表
    【解决方案3】:

    这是我的看法。您需要使用递归来打印出列表。

    function printList(list,container){
        var ul = document.createElement('ul');
        list.forEach(function(item){
            var li = document.createElement('li');
            li.innerHTML = '<div class="meta">' + item.label + '</div>';
            if(item.hasOwnProperty('items')){
                printList(item.items,li);
            }
            ul.appendChild(li);
        });
        container.appendChild(ul);
    }
    

    使用它:

    axios.get('../data/colors.json').then(function (response) {
        printList(response.data.items,document.body);
    })
    

    function printList(list,container){
        var ul = document.createElement('ul');
        list.forEach(function(item){
            var li = document.createElement('li');
            li.innerHTML = '<div class="meta">' + item.label + '</div>';
            if(item.hasOwnProperty('items')){
                printList(item.items,li);
            }
            ul.appendChild(li);
        });
      container.appendChild(ul);
    }
    
    var items = {
       "items":[
          {
             "label":"red",
             "url":"red",
             "items":[
    
             ]
          },
          {
             "label":"blue",
             "url":"#/blue",
             "items":[
                {
                   "label":"green",
                   "url":"#/green"
                },
                {
                   "label":"yellow",
                   "url":"#/yellow"
                },
                {
                   "label":"pink",
                   "url":"#/pink"
                }
             ]
          }
         ]
    }
    
    printList(items.items,document.body);
    
    console.log();

    【讨论】:

      【解决方案4】:

      您可以使用一个简单的递归函数来执行此操作,该函数接受您要附加到的 html 元素和一个对象。这种方法的一个优点是可以在任意深度上工作,并且它可以保持嵌套而不是将所有内容展平。大部分工作都是处理 HTML ——除此之外,这是一个非常简单的想法:

      let obj = {"items":[{"label":"red","url":"red","items":[]},{"label":"blue","url":"#/blue","items":[{"label":"green","url":"#/green"},{"label":"yellow","url":"#/yellow"},{"label":"pink","url":"#/pink"}]}]}
      
      function addItems(parent, obj) {
          let keys = Object.keys(obj)
          for (key of keys) {
            let o = obj[key]      
            let li = document.createElement('li')
            if (Array.isArray(o)) {
              let text = document.createTextNode(key);
              li.appendChild(text)
              let ul = document.createElement('ul')
              o.forEach(item => addItems(ul, item))
              li.appendChild(ul)
            } else {
              li.innerText = key + ': ' + o
            }
            parent.appendChild(li)
          }
      }
      
      let list = document.getElementById('1')
      addItems(list, obj)
      <ul id="1">
      </ul>

      【讨论】:

        【解决方案5】:

        我不认为您正在循环嵌套的 items 数组。您只是在父数组上循环。

        如果嵌套数组中有项目,请为其添加另一个循环。例如

        for (var j in response.data.items[i].items) {
          li.innerHTML = "<a class='meta'>" + response.data.items[i].label + "<div>" + response.data.items[i].items[j].label + "</div>" + "</a>"; // create a new li element
        }
        

        我认为有更好的模式来做一个 for 循环,但我只是在这里保留你的模式。基本上根本原因,你没有循环嵌套项目。

        【讨论】:

          猜你喜欢
          • 2020-09-28
          • 2023-04-10
          • 1970-01-01
          • 2012-04-16
          • 2016-07-15
          相关资源
          最近更新 更多