【问题标题】:Any Javascript or Coffeescript `map` function that transforms object *values*?任何转换对象*值*的Javascript或Coffeescript`map`函数?
【发布时间】:2012-06-11 10:58:28
【问题描述】:

是否没有普遍/标准的 Javascript 或 Coffeescript 函数可以转换对象/地图/哈希的值?

jQuery has $.map 但它只产生Arrays。
Underscore has _.map 但它也只产生Arrays。

需要明确的是,我正在寻找像这样的功能。 (这个例子是用 Coffeescript 而不是 Javascript 编写的。)

# Transforms the values in a map. (Doesn't modify `obj` — returns a new map.)
# Example usage:
#   mapObjVals({ a: 'aa', b: 'bb'}, (key, value) -> value + '_!')
#   --> { a: 'aa_!', b: 'bb_!' }
mapObjVals = (obj, f) ->
  obj2 = {}
  for k, v of obj
    obj2[k] = f k, v
  obj2

【问题讨论】:

  • 您似乎已经回答了您自己的问题 :) 只需确保您使用 for own k, v of obj 以防止被原型扩展所困扰。我会直接使用for 循环而不是辅助函数,因为这种情况很少见。

标签: javascript coffeescript


【解决方案1】:

如果要将对象映射到对象,则需要使用fold(传统功能术语)或reduce(通用现代名称,下划线使用),它从集合中构建新值:

  _.reduce(obj, function(newObj, thisValue, thisKey) { 
      // modify newObj based on thisKey/thisValue
      return newObj;
      }, {})

作为第二个参数传递的函数在每个键/值对中调用一次。它作为第一个参数传入正在构建的对象中,然后是当前值,然后是关联的键。由函数来修改对象并返回其新值。

_.reduce 的第三个参数是新对象的初始值,与第一个键/值对一起传入;在这种情况下,它是一个空对象/地图/哈希{}

Reduce/fold/inject 通常用于求和值。基本上,任何时候你想从一个集合中构造一个新的单个值。 map 实际上只是 reduce 的一个特例,其中据称减少的值实际上是另一个与原始大小相同的集合。

对于 CoffeeScript、AFAIK,列表推导总是返回列表,即使在迭代对象时也是如此。所以你可能想看看the CoffeeScript version of Underscore

【讨论】:

  • 谢谢!我的+ '_!' 示例与_.reduce 一起工作,如下所示:_({ a: 'aa', b: 'bb'}).reduce ((memo, value, index) -> memo[index] = value + '_!'; memo), {}
  • "遗憾地",对于 _.reduce,我必须 1) 从迭代器内部返回 memo,以及 2) 将 {} 传递给 reduce。所以它有点冗长。实际上,我发现我的示例函数更容易理解——当我阅读mapObjVals({ a: 'aa', b: 'bb'}, (key, value) -> value + '_!') 时,我很快就明白了正在做什么。
  • 是的,reduce 更冗长,因为它更通用; map 可以很容易地用 reduce 来实现。你是否觉得需要编写一个辅助函数来隐藏这种冗长取决于个人喜好..
猜你喜欢
  • 2016-11-26
  • 2014-09-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-17
  • 2019-12-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多