使用Underscore,如何以递归方式展平对象数组?

时间:2014-10-20 13:17:02

标签: javascript functional-programming underscore.js

我有一个树/可遍历的对象,如下所示:

                var data = {children: [
                {
                name: 'foo',
                url: 'http://foo',
                children: [
                    {
                    name: 'bar',
                    url: 'http://bar',
                    children: []
                }
                ]
            },
            {
                name: 'baz',
                url: 'http://baz',
                children: []
            },
            {
                name: 'biff',
                children: []
            }
            ]};

我需要做的是能够将数据展平为一维列表:

var flattenedData = [{name: 'foo', url: 'http://foo'}, {name: 'bar', url: 'http://bar'}, {name: 'baz', url: 'http://baz'}, {name: 'biff'}];

目前,我已经创建了一个递归辅助函数来遍历数据结构并将结果推送到数组中。如果可能的话,我想在功能上做得更多。类似的东西:

var flattenedData = _.chain(data.children).flatten().filter(function(item){//real filtering; return item;}).value();

问题是,展平似乎不会使对象数组变平,只是简单的数组。我错了。

如果不在辅助函数中遍历树,我将如何以更实用的方式执行此任务?

1 个答案:

答案 0 :(得分:1)

我不明白你的意思" flatten似乎没有展平一系列对象,只是简单的数组" - 怎么会这样?它绝对可以压扁任何类型的阵列。无论如何,使用reduce

的简单单程解决方案
Object.prototype.flatten = function () {
    if (this instanceof Array) {
        return this.reduce(function(a, b) {
            return a.concat(b.flatten());
        }, []);
    }

    var res = [];

    // this is the example condition
    if (this.url !== undefined) {
        res.push(this);
    }

    return res.concat(this.children.flatten());
};

var flat_data = data.flatten();
print(flat_data);

顺便说一下,建议将Object替换为您想要展平的自定义数据类型,这样就不会弄乱所有对象的全局原型。