展平对象属性列表

时间:2014-12-05 14:27:17

标签: javascript map functional-programming reduce

我发现在使用强制性思维模式多年后,很难以功能性的方式编写这段代码。

给出如下输入:

[{'id': 'foo', frames: ['bar', 'baz']}, {'id': 'two', frames: ['three', 'four']}]

输出应为:

[ { foo: 'bar' }, { foo: 'baz' } { two: 'three' }, { two: 'four' } ]

如何在javascript中以函数式编写这个?

2 个答案:

答案 0 :(得分:2)

首先让我们创建一个给定对象返回帧数组的函数:

function toFrames(obj) {
    var id = obj.id;

    return obj.frames.map(function (frame) {
        var obj = {};
        obj[id] = frame;
        return obj;
    });
}

接下来,我们创建一个concat函数:

function concat(a, b) {
    return a.concat(b);
}

最后我们进行转型:

var input = [{
    id: "foo",
    frames: ["bar", "baz"]
}, {
    id: "two",
    frames: ["three", "four"]
}];

var output = input.map(toFrames).reduce(concat);

自己看演示:



var input = [{
    id: "foo",
    frames: ["bar", "baz"]
}, {
    id: "two",
    frames: ["three", "four"]
}];

var output = input.map(toFrames).reduce(concat);

alert(JSON.stringify(output, null, 4));

function toFrames(obj) {
    var id = obj.id;

    return obj.frames.map(function (frame) {
        var obj = {};
        obj[id] = frame;
        return obj;
    });
}

function concat(a, b) {
    return a.concat(b);
}




不是函数式编程很有趣吗?


解释:

  1. toFrames函数接受一个对象(例如{ id: "foo", frames: ["bar", "baz"] })并返回框架对象列表(即[{ foo: "bar" }, { foo: "baz" }])。
  2. concat函数只是连接两个数组。 .reduce(concat)方法调用将[[a,b],[c,d]]等数组展平为[a,b,c,d]
  3. 给定一个对象的输入列表,我们首先将每个对象转换为一个帧列表,从而得到一个帧对象列表列表。
  4. 然后我们展平嵌套列表以产生所需的输出。
  5. 简单。

答案 1 :(得分:1)

您可以这样做,假设arr是输入

result = []; // array
arr.forEach(function(o) { // go through elements
    for (var i = 0; i < o.frames.length; i++) { // make a since we need to get two objs per element
        var obj = {}; // an object which will be over written for every iteration
        obj[o.id] = o.frames[i]; // set property name and value
        result.push(obj); // finally push it in the array
    }
});