javascript - 如何在不扩展为列表的情况下减少(...)JavaScript Map 对象的条目?

标签 javascript dictionary functional-programming

似乎没有很好的标准库方式来做这样的事情?

let thismap = new Map([[1,2],[2,3]])
console.log(thismap.entries().reduce((prev, [a,b])=>prev + a * b, 0))
Uncaught TypeError: thismap.entries(...).reduce is not a function我认为这是由于 entry() 函数返回了一个迭代器?我不想 Array.from(thismap.entries()).reduce(...) ,因为这会不必要地在内存中构建数组。感觉就像我错过了一些东西,但我也不想重新实现应该在标准库中的东西。
我想如果我改用一个对象(由于其他原因,这里不是一个令人满意的解决方案),entry() 本质上将是一个数组扩展而不是一个迭代器(尽管我认为它可以在考虑内存效率的情况下实现)。但是,我仍然想知道如何减少迭代器

最佳答案

您可以使用 for of循环并手动处理求和。这使用迭代器而不创建临时数组。请注意,这里我们甚至不必调用 entries手动因为 Map.prototype[Symbol.iterator] === Map.prototype.entries .

const map = new Map([[1, 2], [2, 3]])

let sum = 0
for (const [a, b] of map) sum += a * b

console.log(sum)

当然,如果您更频繁地需要它,您当然也可以将其分解为实用功能。这里我创建了一个函数lazyReduce就像 Array.prototype.reduce但对任何类型的迭代进行操作:

function lazyReduce (originalIterable, callback, initialValue) {
  let i = 0
  let accumulator = initialValue
  let iterable = originalIterable
  
  // This part exists to implement the behavior of reduce without initial value
  // in the same way Array.prototype.reduce does it
  if (arguments.length < 3) {
    iterable = iterable[Symbol.iterator]()
    const { value, done } = iterable.next()
    if (done) throw new TypeError('Reduce of empty iterable with no initial value')
    accumulator = value
    i++
  }
  
  for (const element of iterable) {
    accumulator = callback(accumulator, element, i++, originalIterable)
  }
  
  return accumulator
}

const map = new Map([[1, 2], [2, 3]])

console.log(lazyReduce(map, (prev, [a, b]) => prev + a * b, 0))

如果您愿意,可以扩展 Map 的原型(prototype), Set等,即 Map.prototype.reduce = function (...args) { return lazyReduce(this, ...args) } . (注意:其他一些返回迭代器的东西很难扩展,但仍然可能。例如 RegExpStringIterator 不作为全局变量存在,但您仍然可以执行 Object.getPrototypeOf(''.matchAll(/./g)).reduce = ... 。类似的想法适用于 Generator .)

关于javascript - 如何在不扩展为列表的情况下减少(...)JavaScript Map 对象的条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71930179/

相关文章:

java - servlet ArrayList 和 HashMap

functional-programming - fn : 'a -> ' b 类型的 ml 函数

Java 流对映射列表的值求和

javascript - 如何将输入绑定(bind)到 vue.js 模型

javascript - 使用 JPlayer 音频播放器时出现问题

Python:获取两个字典之间的差异

functional-programming - 在 SMLofNJ.Cont 中隔离

javascript - 为什么堆栈跟踪在 .ts 文件中的一行中显示 3 个调用

Javascript 在 IE9 中不工作

python - Query PubMed with Python - 如何从查询中获取所有文章详细信息到 Pandas DataFrame 并以 CSV 格式导出