在JavaScript中将对象数组转换为嵌套对象的函数

时间:2014-04-18 10:02:52

标签: javascript arrays object recursion nested

我是JS的新手。请帮助我为我的Web应用程序编写一个很好的函数。

我有一系列"谚语" - 对象类

 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 个答案:

答案 0 :(得分:1)

我希望您不要介意我使用对象({})来表示树而不是数组([]),这样可以更轻松地搜索现有字母,系列字母只有1根(字母),我觉得这很有道理。在这种情况下,您实际上并不需要递归,因为您的初始条目只是一个我们可以迭代一次的平面列表。我在使用V8 JavaScript引擎的Node.js中对此进行了测试。使用带有字母键的对象确实可以使用#letter;顺便进入对象本身就是多余的。

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