6

标题中的短代码在 Haskell 中,它执行以下操作

list.map {|x| x + 1}

在红宝石中。

虽然我知道这种方式,但我想知道的是,有没有更优雅的方式可以像在 Haskell 中那样在 ruby​​ 中实现相同的东西。

我真的很喜欢to_procruby​​ 中的快捷方式,比如这种形式:

[1,2,3,4].map(&:to_s)
[1,2,3,4].inject(&:+)

但这仅接受 Proc 和方法之间完全匹配的参数编号。

我正在尝试寻找一种方法,允许将一个或多个参数额外传递到 Proc 中,而不像第一个演示那样使用无用的临时块/变量。

我想这样做:

[1,2,3,4].map(&:+(1))

ruby 有类似的方式来做到这一点吗?

4

6 回答 6

7

如果您只想添加一个,那么您可以使用以下succ方法

>> [1,2,3,4].map(&:succ)
=> [2, 3, 4, 5]

如果要添加两个,可以使用 lambda:

>> add_2 = ->(i) { i + 2 }
>> [1,2,3,4].map(&add_2)
=> [3, 4, 5, 6]

对于任意值,您可以使用构建 lambdas 的 lambda:

>> add_n = ->(n) { ->(i) { i + n } }
>> [1,2,3,4].map(&add_n[3])
=> [4, 5, 6, 7]

您还可以使用 lambda 生成方法:

>> def add_n(n) ->(i) { i + n } end
>> [1,2,3,4].map(&add_n(3))
=> [4, 5, 6, 7]
于 2012-05-25T19:24:04.480 回答
5

使用ampex gem,它允许您使用方法X来构建任何 proc 一对一变量。这是其规范中的一个示例:

["a", "b", "c"].map(&X * 2).should == ["aa", "bb", "cc"]
于 2012-05-25T19:30:55.550 回答
3

你不能直接用 default 来做map。但是,实现支持这种功能的版本非常容易。例如,Ruby Facets就包含了这样一个方法:

require 'facets/enumerable'

[1, 2, 3, 4].map_send(:+, 10)
=> [11, 12, 13, 14]

实现如下所示:

def map_send(meth, *args, &block)
  map { |e| e.send(meth, *args, &block) }
end
于 2012-05-25T19:27:23.013 回答
2

In this particular case, you can use the following:

[1, 2, 3, 4].map(&1.method(:+))

However, this only works because + is not associative. It wouldn't work for -, for example.

于 2012-05-25T23:02:57.573 回答
1

Ruby 没有内置支持此功能,但您可以创建自己的扩展或使用小型 gem ' ampex '。它定义了具有扩展“to_proc”功能的全局变量 X。

它使您有可能做到这一点:

[1,2,3].map(&X.+(1))

甚至是:

"alpha\nbeta\ngamma\n".lines.map(&X.strip.upcase) 
于 2012-05-25T19:32:46.470 回答
0

如果只想加 1,可以使用nextor succ

[1,2,3,4].map(&:next)
[1,2,3,4].map(&:succ)
于 2012-05-25T19:21:06.090 回答