2014-11-28 3 views
0

У меня есть список объектов в массивеПреобразовать массив объектов с вложенной уль литий Элементы

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'}); 

Я хочу, чтобы преобразовать эти вещи в надлежащем списке с ул и Ли, также уровни листинга зависит от myLevel переменная.

  • Книга 1
    • тема 1
      • MCQ
      • MTF
    • тема 2
      • выдумка
  • Книга 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
      • выдумка
    • тему 1
      • MTF
  • Книга 2
    • тема 1
      • MCQ

Вот книга 1 имеет две темы 1. что неверно. Мне нужно только 1 тема 1. и что тема 1 должна иметь как mcq, так и mtf.

JSFiddle link

Благодаря

ответ

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

Я надеюсь, что это помогает.

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/

+0

спасибо jivings, но дублированные узлы неверны. Тема 1 имеет три mcq, должно быть только 1. –

+0

@AshokShah. Там вы идете, я добавил «indexOf» в микс. – Jivings

+0

Спасибо, этот ответ полезен. Но узлы должны зависеть от переменной myLevel, для уровней вложенности. Любая идея была бы большой помощью –