【问题标题】:Map-Reduce in Node节点中的 Map-Reduce
【发布时间】:2015-04-06 21:22:20
【问题描述】:

我有我的array=[{id:"1"}, {id:"2"}, {id:"3"}] 并想将其转换为对象:{"1":true, "2", true, "3":true}; 所以我做了以下事情:

async.reduce(myArray, {}, function (memo, item, callback) {
    memo[item.id] = true;
    callback(null, memo);
}, function (err, myObj) {
    console.log("converted object", myObj);
}

它可以完成这项工作,但是我不确定这在性能方面是否有意义还是毫无意义? Here 他们建议使用 map reduce,但我仍然很困惑如何使用 map 和 reduce 来提高性能;任何帮助表示赞赏。

谢谢

【问题讨论】:

  • 那么这个reduce内部是否有任何异步发生,或者换句话说,您正在迭代异步操作中使用的东西,对吗?否则根本没有意义!
  • 如果您正在执行同步操作,则使用 async 完全没有意义。它只会让你慢下来。

标签: javascript node.js asynchronous mapreduce async.js


【解决方案1】:

在您的情况下,您的 reduce 函数中没有任何异步内容,因此您最好使用常规的 Array.prototype.reduce:

var array = [{id:"1"}, {id:"2"}, {id:"3"}];
var newArray = array.reduce(function(cur, val) {
    cur[val.id] = true;
    return cur;
}, {});

console.log(newArray);
// => { '1': true, '2': true, '3': true }

【讨论】:

  • 你的比较不对;这不是 async.reduce 的正确用法;当您有回调并且调用的性质是异步时使用 async.reduce!很明显,在您的示例中 Array.prototype.reduce 获得了更好的性能结果,因为您在 async.reduce 中的操作不是异步的!
  • 是的,我认为这种比较有些奇怪。无论如何,我回滚了那个编辑。谢谢。
【解决方案2】:

如果它可能是一个潜在的大数组并且标准 JavaScript Array.prototype.reduce 循环会花费太长时间,导致服务器挂起(在执行该循环时无法响应请求),则进行异步调用也可能很有用.

异步操作将比 Array.prototype.reduce、forEach 或 map 花费更长的时间,但这是值得的,因为服务器可以在完成请求之前(在步骤之间)回答请求。

您也可以使用异步的回调来获取每个步骤的部分计算。

如果数组永远不会那么大并且您不需要部分结果,您应该坚持使用标准数组的同步方法。

【讨论】:

    【解决方案3】:

    方法 1 - 同步归约(最接近给定的代码)

    虽然async 库的reduce 函数很有用,但只有在reduce 操作执行异步操作(带有回调的操作)时才需要。对于简单和同步的任务,原生 Javascript Array.reduce 方法就足够了。

    // given myArray like [{id:"1"}, {id:"2"}, {id:"3"}]
    
    var newObject = myArray.reduce(function(obj, current){
        obj[current.id] = true;
        return obj;
    }, {}); // { '1': true, '2': true,'3': true }
    

    方法 2 - Array.forEach

    通过创建一个空对象,然后循环遍历数组并添加到它,此方法将产生相同的结果。

    // given myArray like [{id:"1"}, {id:"2"}, {id:"3"}]
    
    var newObject = {};
    
    myArray.forEach(function(element){
        newObject[element.id] = true;
    });
    
    // newDictionary is now { '1': true, '2': true,'3': true }
    

    方法 2½ - 数组而不是对象

    如果对象的所有键 (ids) 都是整数,则可以考虑使用数组而不是对象。

    使用数组的方法 1: [{}].concat(myArray) 将变为 [[]].concat(myArray)

    使用数组的方法 2: }, {}); 将更改为 }, []);

    祝你好运!

    【讨论】:

    • 不,您不想添加对象。你想把它作为第二个参数提供给reduce!!!
    • @Bergi 感谢您的反馈。答案已更新以反映这一点。 (我会说,虽然添加它绝对既不优雅也不高效,但它会正常工作)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-07
    • 1970-01-01
    • 2019-11-12
    • 1970-01-01
    • 2014-03-21
    • 1970-01-01
    相关资源
    最近更新 更多