首页 > 解决方案 > Aggregate values obtained from a callback function in ES6?

问题描述

I have a class that exposes a way to enumerate some values (which may not be stored nicely in an array or other built-in collection):

class DataStore {
  constructor(values) {
    this.values = values;
  }
  forEachData(callback) {
    // the callback is invoked with items specific to the logic of DataStore
    callback(0);
    callback(1);
    for (const x of this.values) {
      callback(x);
    }
    for (const x of this.values) {
      callback(2 * x);
    }
  }
}

In another function that uses this class, I would like to perform some kind of aggregation (i.e. reduction) operation on the values returned by the callback. Is there a concise way to express this using Array.prototype.reduce() or some other built-in way without doing the reduction manually?

// Inside my function
const data_store = ...; // DataStore object
const aggregate_op = (accumulator, current_value) => Math.min(accumulator, f(current_value));

// I'm wondering if there is a built-in language or library feature that does this kind of reduction:
let answer = 0;
data_store.forEachData(x => {
  answer = aggregate_op(answer, x);
});

Note: It is simple enough to do the reduction manually as above, but arguably, array reduction is also very simple without using Array.prototype.reduce():

const arr = [1, 3, 5, 7, 9];
let answer = 0;
arr.forEach(x => {
  answer = aggregate_op(answer, x);
});

标签: javascriptecmascript-6reduction

解决方案


您确实可以实现自己的reduce功能。你几乎已经做到了:

class DataStore {
  constructor(values) { /* constructor logic */ }

  forEachData(callback) { /* forEach logic */}

  reduce(callback, initialValue) {
    let value = initialValue;
    this.forEachData(function(x){
      value = callback(value, x);
    });

    return value;
  }
}

用法:

let answer = data_store.reduce(aggregate_op, 0);

有没有办法在不重新发明轮子的情况下自动执行此操作?有点。这取决于你如何管理你的价值观。您可以简单地继承表单Array

class DataStore extends Array { /* ... */ }

在这里,您不能编写自己的forEachData方法,而是使用forEach并且不硬编码0and1值,而是将其实际插入对象的内部数据数组中。这也意味着你必须坚持数组语义——没有字符串索引,没有稀疏索引等。

如果您可以忍受 Array 的限制,那么这是一种无需编码即可继承许多功能的简单方法。否则你需要实现你自己的reduce()


推荐阅读