将数组对象转换为嵌套的ul li元素

时间:2014-11-28 12:05:26

标签: javascript jquery html arrays object

我有一个数组中的对象列表

var myLevel = ['sub', 'topic', 'type'];

var myCollection = new Array();
myCollection.push({sub: 'Book 1', topic: 'topic 1', type: 'mcq'});
myCollection.push({sub: 'Book 1', topic: 'topic 1', type: 'mcq'});
myCollection.push({sub: 'Book 1', type: 'fib', topic: 'topic 2'});
myCollection.push({sub: 'Book 1', topic: 'topic 1', type: 'mtf'});
myCollection.push({sub: 'Book 1', topic: 'topic 1', type: 'mcq'});
myCollection.push({sub: 'Book 2', type: 'mcq', topic: 'topic 1'});
myCollection.push({sub: 'Book 2', topic: 'topic 1', type: 'mcq'});
myCollection.push({sub: 'Book 2', topic: 'topic 1', type: 'mcq'});

我想用ul和li将这些内容转换为正确的列表,列表的级别也依赖于myLevel变量。     

            
  • 第1册             
                      
    • 主题1                     
                                
      • MCQ
      •                         
      • MTF
      •                     
                      
    •                 
    • 主题2                     
                                
      • FIB
      •                     
                      
    •             
            
  •         
  • 第2册             
                      
    • 主题1                     
                                
      • MCQ
      •                     
                      
    •             
            
  •     

每个部分都有一个独特的孩子,没有重复的孩子。

我尝试了这段代码,但它会生成重复的孩子

var dom="<ul>";
var used = new Array();
var currentItems = new Array(myLevel.length);
var lastJ = -1;

for(var i=0; i<myCollection.length; i++)
{
    var con = false;
    for(var k=0; k<used.length; k++){
        if(compareObjects(used[k], myCollection[i]))
            con = true;
    }
    if(!con){
        for(var j=0; j<myLevel.length; j++){
            if(currentItems[j] !== myCollection[i][myLevel[j]]){
                if(lastJ !== -1){
                    for(var l=0; l<lastJ-j; l++){
                        dom+="</ul></li>";   
                    }
                }
                for(var l=j+1; l<currentItems.length; l++)
                    currentItems[l] = "";
                currentItems[j] = myCollection[i][myLevel[j]];
                dom+="<li>"+currentItems[j]+(j<myLevel.length-1?"<ul>":"");
                lastJ = j;
            }
        }
        used.push(myCollection[i]);
    }
}
dom+="</ul>";
$('body').html(dom);

function compareObjects(obj1, obj2){
    if(obj1.length != obj2.length)
        return false;
    for(var el in obj1){
        if(obj2[el] === undefined)
            return false;
        if(obj1[el] !== obj2[el])
            return false;
    }
    return true;
}

我得到以下结果     

            
  • 第1册             
                      
    • 主题1                     
                                
      • MCQ
      •                     
                      
    •                 
    • 主题2                     
                                
      • FIB
      •                     
                      
    •                 
    • 主题1                     
                                
      • MTF
      •                     
                      
    •             
            
  •         
  • 第2册             
                      
    • 主题1                     
                                
      • MCQ
      •                     
                      
    •             
            
  •     

这里的书1有两个主题1.这是不正确的。 我只需要1个主题1.主题1应该同时包含mcq和mtf。

JSFiddle link

由于

2 个答案:

答案 0 :(得分:1)

听起来你可以做reduce

var newCollection = myCollection.reduce(function (p, v) {
    var book = p[v.sub];
    // if we haven't seen this book before...
    if (!book) {
        book = p[v.sub] = {};
    }
    // if we haven't seen this topic before...
    if (!book[v.topic]) book[v.topic] = [];
    // if we haven't seen this type before...
    if (book[v.topic].indexOf(v.type) !== -1) book[v.topic].push(v.type);
    return p;
}, {})

哪个输出:

{
  "Book 1": {
    "topic 1": [
      "mcq"
      "mtf"
    ],
    "topic 2": [
      "fib"
    ]
  },
  "Book 2": {
    "topic 1": [
      "mcq"
    ]
  }
}

这是一个工作小提琴:http://jsfiddle.net/kL1kud34/1/

答案 1 :(得分:1)

使用下面给出的代码:

var $out;
$(document).ready(function()
{

    for(var i=0; i<myCollection.length; i++)
    {
        $out = $('#out');
        for(var j=0; j<levelTree.length; j++)
        {
            var itemName = myCollection[i][levelTree[j]];
            var level = j;

            /**********************************************************/


                var $con;
                if($out.children().eq(0).length == 0)
                {
                    $con = $('<ul></ul>');
                    $con.append('<li>'+ itemName + '</li>');
                    $out.append($con);
                }
                else
                {
                    var flag = $out.children().eq(0).children().filter(function(i, e)
                    {
                         return (this.childNodes[0].textContent == itemName);
                    });
                    console.log(flag.length);
                    if(flag.length == 0)
                    {
                        $out.children().eq(0).append('<li>' + itemName + '</li>');
                    }
                }

                var ele = $out.children(0).eq(0).children().filter(function(i, e)
                {
                    return (this.childNodes[0].textContent == itemName);
                }).get();
                $out = $(ele);


            /**********************************************************/
        }
    }
});

JSFiddle link

我希望它有所帮助。