【问题标题】:Creating a multi-level array from DOM elements' data attributes in jQuery在 jQuery 中从 DOM 元素的数据属性创建多级数组
【发布时间】:2013-12-18 20:49:39
【问题描述】:

好的,这可能是一个简单的循环问题,我只是想多了(与第一次相去甚远),但我将发布此问题,以防有人能快速回答我.

我有一个这样的 DOM 元素数组:

<ul id="array">
  <li class='item' data-id="1">
    <ul class="child">
      <li class='item' data-id="2"></li>
      <li class='item' data-id="3"></li>
    </ul>
  </li>
  <li class='item' data-id="4"></li>
  <li class='item' data-id="5">
    <ul class="child">
      <li class='item' data-id="6"></li>
      <li class='item' data-id="7">
        <ul class="child">
          <li class='item' data-id="8"></li>
          <li class='item' data-id="9"></li>
          ...
        </ul>
      </li>
    </ul>
  </li>
</ul>

我想使用 jQuery 循环并得出类似的结果:

var result = [
  {
    "id":1,
    "children":[
      {
        "id":2,
        "children":[]
      }, 
      {
        "id":3,
        "children":[]
      }
    ]
  },
  { 
    "id": 4,
    "children":[]
  },
  {
    "id": 5,
    "children":[
      {
        "id":6,
        "children":[]
      }, 
      {
        "id":7,
        "children":[
          {
            "id":8,
            "children":[]
          }, 
          {
            "id":9,
            "children":[]
          }
        ]
      }
    ]
  }
]

(请注意,为了便于阅读,明显间隔了 :))

如果这是子 ul 项目的确切数量,那将是一个简单的循环。我遇到的问题是列表项树可以根据用户的需要向下多级(实际上,它会在某个时候停止,但你明白了)所以它需要继续循环遍历树直到那里没有了。

【问题讨论】:

    标签: javascript jquery arrays map custom-data-attribute


    【解决方案1】:

    为此,您需要一个递归函数和map() 方法:

    function extract() {
        var $this = $(this);
    
        return {
            id: $this.data('id'),
            children: $this
                .find('> .child > .item')
                .map(extract)
                .get()
        };
    }
    
    var output = $('#array > .item')
        .map(extract)
        .get();
    

    演示:http://jsfiddle.net/pj2C2/1/

    【讨论】:

    • 干得好!谢谢!这非常简洁,效果很好:)
    【解决方案2】:

    这对我有用:

    function arrayRecursive($arr) {
        var result = [];
    
        // with > .item you go only 1 level deeper per step
        $arr.find('> .item').each(function(index, item) {
            var obj = {};
            obj.id = $(item).attr('data-id');
            obj.children = arrayRecursive($(item).find('.child'));
            result.push(obj);
        });
    
        return result;
    }
    
    var result = arrayRecursive($('#array'));
    
    // Test the result with a stringified alert
    alert(JSON.stringify(result));
    

    编辑: 删除了if ($(item).find('.child').length &gt; 0),因此默认为空数组。

    【讨论】:

    • 有效,但我会避免在函数内创建新的 jQuery 对象,如下所示:jsfiddle.net/nZ3BJ
    • 我没有选择这个作为答案但是确实给了它一个赞成票,因为它确实很好用!我发现@Pavio 的答案更简洁一些,但感谢您这样做!非常感谢您的努力。
    【解决方案3】:

    听起来像是一个递归问题。

    因此,您可以循环遍历 li 元素,检查子元素是否为 ul 元素,如果是,则另一个级别的递归将值存储在该级别。

    一些粗略的伪代码

    readElements($("#array").children());
    
    function readElements(array) {
        var elementsArray = [];
        for (var i = 0; i < array.length; i++) {
           if ($($(array[i]).children()[0]).is("ul")) {
               return readElements($(array[i]).children());
           }
           elementsArray.push({ id: getId(), children: [] });
           // add id elementArrays
        }
        return elementsArray;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-09-12
      • 2012-04-13
      相关资源
      最近更新 更多