2014-04-18 89 views
0

我是JS的新手。请帮助我为我的Web应用程序编写一个很好的功能。在JavaScript中将对象数组转换为嵌套对象的函数

我有“说法”的数组 - 反对那种

story = [ 
    { letters:'B', 
     head:'heading', 
     text:'text', 
     img:'img' 
    }, 
    { letters:'B|A', 
     head:'heading', 
     text:'text', 
     img:'img' 
    }, 
    { letters:'B|A|E', 
     head:'heading', 
     text:'text', 
     img:'img' 
    }, 
    { 
     letters:'K|A', 
     head:'heading', 
     text:'text', 
     img:'img' 
    }, 
    { 
     letters:'K', 
     head:'heading', 
     text:'text', 
     img:'img' 
    }] 

的“字母”属性是一个嵌套的树中的“说”的地址。地址由任意数量的大写字母组成,不允许使用数字或特殊符号。 |是分隔符。我需要编写一个函数来此数组转换为一棵树种:

tree = [ 
    { letter:'B', 
     letters:'B', 
     head:'heading', 
     text:'text', 
     img:'img' 
     nest: [{ letter:'A', 
        letters:'B|A', 
        head:'heading', 
        text:'text', 
        img:'img' 
        nest:[{ letter:'E', 
           letters:'B|A|E', 
           head:'heading', 
           text:'text', 
           img:'img' 
          }] 
       }] 

    }, 
    { letter:'K', 
     letters:'K', 
     head:'heading', 
     text:'text', 
     img:'img' 
     nest:[{ letter:'A', 
       letters:'K|A', 
       head:'heading', 
       text:'text', 
       img:'img' 
       }] 
    }] 

据我所知,这里需要递归函数,但它太困难,我要弄清楚如何将功能可有效转换阵列,而不释放父母面前的孩子地址的“说法”。在AngularJS Web应用程序中,该函数必须快速将大数组转换为树。

感谢您的帮助!

回答

1

我希望你不介意我用一个对象({})来表示树而不是数组([]),这使得搜索现有字母更容易,并且由于每个字母系列只有一个根(字母),我认为这是有道理的。在这种情况下,您实际上不需要递归,因为您的初始条目只是一个我们可以迭代一次的平坦列表。我在使用V8 JavaScript引擎的Node.js中测试了这一点。使用带有字母键的对象确实会使对象本身中的'字母'条目变得多余。

var tree = {}; 

for(var i = 0; i < story.length; i++) { 
    var saying = story[i]; 
    var letters = saying.letters.split('|'); 

    var search = tree; 
    for(var j = 0; j < letters.length; j++) { 
     var letter = letters[j]; 

     var obj = letter in search ? search[letter] : search[letter] = {}; 

     // Endpoint, assign letter and values to obj 
     if(j == letters.length - 1) { 
      obj.letter = letter; 
      for(key in saying) { 
       obj[key] = saying[key]; 
      } 
     } else { // Create nested object and update search object 
      search = 'nest' in obj ? obj.nest : obj.nest = {}; 
     } 
    } 
}; 

// Output: 
// { B: 
// { letter: 'B', 
//  letters: 'B', 
//  head: 'heading', 
//  text: 'text', 
//  img: 'img', 
//  nest: 
//  { A: 
//   { letter: 'A', 
//   letters: 'B|A', 
//   head: 'heading', 
//   text: 'text', 
//   img: 'img', 
//   nest: 
//    { E: 
//    { letter: 'E', 
//     letters: 'B|A|E', 
//     head: 'heading', 
//     text: 'text', 
//     img: 'img' } } } } }, 
// K: 
// { nest: 
//  { A: 
//   { letter: 'A', 
//   letters: 'K|A', 
//   head: 'heading', 
//   text: 'text', 
//   img: 'img' } }, 
//  letter: 'K', 
//  letters: 'K', 
//  head: 'heading', 
//  text: 'text', 
//  img: 'img' } } 
+0

是啊,这对我的作品好!以为Angular需要在'ng-repeat'指令中使用一个数组,但它对于你所建议的对象来说效果很好。似乎排序输出可能会有一些困难,但我还不确定。 –

+0

我检查了'ng-repeat'的兼容性。该对象工作正常,但为了排序输出,它应该是一个数组。但是,Angular有一个小小的过滤器,这使得它成为一个动态数组,并且一切正常。这里是:http://adamkdean.co.uk/blog/read/117/ordering-and-filtering-objects-with-ng-repeat 非常感谢你,Daniël! –

+0

很高兴我能帮忙:-) –

相关问题