使用Lo-Dash 3.0转换值时,groupBy有什么好方法吗?

mme*_*ane 6 javascript lodash

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

var data = [
    {key: 'a', val: '1'}, 
    {key: 'a', val: '2'}, 
    {key: 'b', val: '3'}, 
    {key: 'c', val: '4'}, 
    {key: 'c', val: '5'}, 
    {key: 'c', val: '6'}
];
Run Code Online (Sandbox Code Playgroud)

我想把它转换成这个:

var desiredResults = {
    'a': [1, 2], 
    'b': [3], 
    'c': [4, 5, 6]
};
Run Code Online (Sandbox Code Playgroud)

到目前为止,我已经找到了两种实现这一目标的方法lodash-fp,但我仍然想知道是否有更好的方法.

第一种方式是程序性的:

var out = _(data)
    .transform(function(out, item) {
        out[item.key] = out[item.key] || [];
        out[item.key].push(item.val);
    }, {});
Run Code Online (Sandbox Code Playgroud)

第二种方式是我希望实现的无点样式:

var out = _(data)
    .groupBy(_.property('key'))
    .mapValues(_.map(_.property('val')))
    .value();
// Yes, I know that _.property is implied if I just pass a string
Run Code Online (Sandbox Code Playgroud)

但是,这比我想要的更混乱:我必须迭代中间结果来转换分组值,我认为它模糊了代码试图完成的内容.不过,我无法先改变,因为我想要的转换会删除键!

有没有像groupByTransforming(groupIteratee, transformIteratee)方法一样的东西?

小智 2

我对 LoDash 一无所知(抱歉),但我有一个简单的函数,只需使用 vanilla JS 即可完成您想要的操作:

/**
 * Maps an array of objects into a single object,
 * grouped by one property and supplying another.
 * @param  {Array}  input     The array of objects containg data
 * @param  {String} groupBy   The name of the property to group the elements by
 * @param  {String} groupProp The property to push into each array
 * @return {Object}           The mapped object.
 */
function mapToObject(input, groupBy, groupProp) {

    var obj = {};

    // Loop through the data
    input.forEach(function (data) {
        // If the output object doesn't contain the key,
        // make it as an empty array
        if (!obj[data[groupBy]]) {
            obj[data[groupBy]] = [];
        };
        // Push the value into the obj[groupBy] array
        obj[data[groupBy]].push(data[groupProp]); 
    });

    return obj;

}
Run Code Online (Sandbox Code Playgroud)

在你的情况下,你会像这样使用它:

mapToObject(data, 'key', 'val'),因此它会返回按 'key' 分组并具有 'val' 值的数据对象。请参阅下面的代码片段作为示例:

/**
 * Maps an array of objects into a single object,
 * grouped by one property and supplying another.
 * @param  {Array}  input     The array of objects containg data
 * @param  {String} groupBy   The name of the property to group the elements by
 * @param  {String} groupProp The property to push into each array
 * @return {Object}           The mapped object.
 */
function mapToObject(input, groupBy, groupProp) {

    var obj = {};

    // Loop through the data
    input.forEach(function (data) {
        // If the output object doesn't contain the key,
        // make it as an empty array
        if (!obj[data[groupBy]]) {
            obj[data[groupBy]] = [];
        };
        // Push the value into the obj[groupBy] array
        obj[data[groupBy]].push(data[groupProp]); 
    });

    return obj;

}
Run Code Online (Sandbox Code Playgroud)