在jQuery中从DOM元素的数据属性创建一个多级数组

时间:2013-12-18 20:49:39

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

好的,这个可能是一个简单的循环问题,我只是在思考(距离第一次很远)但是我要发布这个只是因为某人有快速回答我

我有一个像这样的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循环使用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项的确切数量,那将是一个简单的循环。我遇到的问题是列表项树可以像用户想要的那样降低多少级别(实际上,它会在某个时刻停止但你得到了想法)所以它需要继续循环遍历树,直到那里不再是。

3 个答案:

答案 0 :(得分:3)

你需要一个递归函数和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/

答案 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 > 0),因此默认为空数组。

答案 2 :(得分:0)

听起来像递归问题。

因此,您可以循环遍历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;
}