汇总从ES6中的回调函数获得的值?

时间:2019-06-03 08:34:30

标签: javascript ecmascript-6 reduction

我有一个类,提供了一种枚举一些值的方法(这些值可能无法很好地存储在数组或其他内置集合中):

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

在另一个使用此类的函数中,我想对回调返回的值执行某种聚合(即归约)操作。是否有一种简洁的方法可以使用Array.prototype.reduce()或其他内置方法来表达此信息,而无需手动进行归约?

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

注意:手动进行上述约简操作非常简单,但是可以说,不使用Array.prototype.reduce(),数组约简也非常简单:

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

1 个答案:

答案 0 :(得分:0)

您确实可以实现自己的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并且不对01值进行硬编码,而是将其实际插入对象的内部数据数组。这也意味着您必须坚持数组语义-没有字符串索引,没有稀疏索引等。

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