能够转换对象*值*的任何Javascript或Coffeescript `map`函数是什么?

9

是否没有通用/标准的Javascript或Coffeescript函数,可以转换对象/映射/哈希表的值?

jQuery有$.map,但它只生成Array
Underscore有_.map,但它也只生成Array

明确一下,我正在寻找像这个例子中的函数。(此示例使用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

1
你似乎已经回答了自己的问题 :) 只要确保使用 for own k, v of obj 来防止被原型扩展所影响。我会直接使用 for 循环而不是帮助函数,因为这是一个罕见的情况。 - Ricardo Tomasi
1个回答

6
如果您想将一个对象映射到另一个对象,您需要使用“fold”(传统函数术语)或“reduce”(常见的现代名称,由underscore使用),从集合中构建一个新值:
  _.reduce(obj, function(newObj, thisValue, thisKey) { 
      // modify newObj based on thisKey/thisValue
      return newObj;
      }, {})

作为第二个参数传递的函数将针对每个键/值对调用一次。它被传递到正在构建的对象中作为其第一个参数,接着是当前值,然后是关联的键。由函数修改对象并返回其新值。 _.reduce 的第三个参数是新对象的初始值,在第一个键/值对中传递;在这种情况下,它是一个空对象/映射/哈希 {}
Reduce/fold/inject 通常用于汇总值。基本上,任何时候您都想从集合中构造一个新的单一值。map 实际上只是 reduce 的一个特殊情况,其中所谓的约简值实际上是与原始大小相同的另一个集合。
对于 CoffeeScript,据我所知,列表推导式始终返回列表,即使迭代对象也是如此。因此,您可能需要查看 Underscore 的 CoffeeScript 版本

谢谢!我已经用_.reduce让我的 + '_!' 示例正常工作了,代码如下:_({ a: 'aa', b: 'bb'}).reduce ((memo, value, index) -> memo[index] = value + '_!'; memo), {} - KajMagnus
1
遗憾的是,使用_.reduce,我必须1)从迭代器内部返回memo,并且2)将{}传递给reduce。因此,它有点冗长。实际上,我发现我的示例函数更容易理解--当我阅读mapObjVals({ a: 'aa', b: 'bb'}, (key, value) -> value + '_!')时,我很快就能理解正在做什么。 - KajMagnus
是的,reduce更冗长,因为它更通用;map可以很容易地通过reduce实现。是否需要编写帮助函数来隐藏这种冗长取决于个人喜好。 - Mark Reed

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接