1

给定一个像这样的对象数组:

[
    { x: 'x1', y: 'y1' },
    { y: 'y2', z: 'z1' },
    { z: 'z2', x: 'x2' } 
]

我想产生一个像这样的对象:

{
    x: [ 'x1', 'x2' ],
    y: [ 'y1', 'y2' ],
    z: [ 'z1', 'z2' ] 
}

我正在使用 ES5 或 underscore.js 函数(如 map/reduce/etc)在 JavaScript 中寻找函数式编程风格的解决方案。

4

3 回答 3

3

也许像下面这样?

var array = [ { x: 'x1', y: 'y1' },
              { y: 'y2', z: 'z1' },
              { z: 'z2', x: 'x2' }
            ];

var result = array.reduce(function(res, obj) {
    Object.keys(obj).map(function(k) {
        if (!res[k])
            res[k] = [];
        res[k].push(obj[k]);
    });
    return res;
}, {});

请注意,我认为大多数人会发现这比循环方法更令人困惑:

var result = {};
for (var i = 0; i < array.length; i++) {
    for (var k in array[i]) {
        if (!result[k])
            result[k] = [];
        result[k].push(array[i][k]);
    }
}
于 2013-08-14T17:14:59.957 回答
0

这是使用下划线的解决方案

var _ = require("underscore");

var arr = [
    { x: 'x1', y: 'y1' },
    { y: 'y2', z: 'z1' },
    { z: 'z2', x: 'x2' }
];


var data = _.reduce(_.flatten(_.map(arr, _.pairs),true), function (memo, value) {
        if (!memo.hasOwnProperty(value[0])) {
            memo[value[0]] = [];
        }
        memo[value[0]].push(value[1]);
        return memo;
    },
    {});

console.log(data);
于 2013-08-14T18:40:43.097 回答
0

一种使用下划线的非常规方法groupBy,它完全忽略了属性名称并使用值的第一个字符:

var arr = [
    { x: 'x1', y: 'y1' },
    { y: 'y2', z: 'z1' },
    { z: 'z2', x: 'x2' }
];
return _.groupBy( _.flatten(_.map(arr, _.values)), 0);

一种完全实用的方法将用于进行reduce分组:

return _.reduce( arr, function(m, obj) {
    return _.reduce( obj, function(m, val, key) {
        (m[key] || (m[key] = [])).push(val);
        return m;
    }, m);
}, {});
于 2013-08-14T19:11:49.850 回答