Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 试图找到一种美观的方法来使用函数式编程风格转换此数组_Javascript_Functional Programming_Underscore.js - Fatal编程技术网

Javascript 试图找到一种美观的方法来使用函数式编程风格转换此数组

Javascript 试图找到一种美观的方法来使用函数式编程风格转换此数组,javascript,functional-programming,underscore.js,Javascript,Functional Programming,Underscore.js,给定如下对象数组: [ { x: 'x1', y: 'y1' }, { y: 'y2', z: 'z1' }, { z: 'z2', x: 'x2' } ] { x: [ 'x1', 'x2' ], y: [ 'y1', 'y2' ], z: [ 'z1', 'z2' ] } 我想制作一个像这样的对象: [ { x: 'x1', y: 'y1' }, { y: 'y2', z: 'z1' }, { z: 'z2',

给定如下对象数组:

[
    { x: 'x1', y: 'y1' },
    { y: 'y2', z: 'z1' },
    { z: 'z2', x: 'x2' } 
]
{
    x: [ 'x1', 'x2' ],
    y: [ 'y1', 'y2' ],
    z: [ 'z1', 'z2' ] 
}
我想制作一个像这样的对象:

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

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

可能类似于以下内容

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]);
    }
}
var result={};
对于(var i=0;i
下面是一个使用下划线的解决方案

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);

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

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);
}, {});

你是说ES5?这并不重要。我认为您应该使用
reduce
,但我不确定这是我在使其完全功能化方面的拙劣尝试:您是对的,它们从ES5开始就存在了。是的,reduce似乎是一种方法(将一个数组简化为一个对象),但我之前找不到一个好的解决方案。很好,我忘记了使用
object.keys()
来利用数组方法;否则,我只能考虑使用
for
循环(就像你的第二个示例)呵呵,groupBy很不错,但事实上,值以与键相同的字母开头只是为了使示例易于绘制,当然值可以是任何东西;)