将块变量传递给grep?

时间:2013-11-26 04:22:51

标签: ruby grep

当我这样做时:

["bar","quax"].grep(/bar/)

输出结果为:

=> ["bar"]

如果我这样做:

["bar","quax"].grep(/fish/)

输出结果为:

=> []

我决定尝试将一个块传递给grep,但它没有用。

["foo", "bar", "baz", "quax"].each do |some_word|
   ["fish","jones"].grep(/some_word/)
end

输出结果为:

=> ["foo", "bar", "baz", "quax"]

我很好奇为什么我的扩展不起作用,因为它看起来相当简单。或者,这样做是否违法?

2 个答案:

答案 0 :(得分:0)

each正在迭代你的数组,但你没有修改它。所以它只是循环几次,调用grep实际上什么都不做(技术上它正在返回某些东西,你只是没有用它做任何事情),然后返回原始数组。

你需要用grep的返回值做一些事情 - 但我不清楚应该是什么(我不明白你为什么要使用each?)

此外,在这种情况下,some_word字面上被视为“some_word”。您应该像.grep(/#{some_word}/)

那样插入正则表达式

答案 1 :(得分:0)

["foo", "bar", "baz", "quax"].each do |some_word|
   ["fish","jones"].grep(/some_word/)
end

不正确。 some_word是块的参数,但/some_word/是与字符串'some_word'匹配的正则表达式,无论是整个字符串还是仅仅是子字符串:

%w[some_word not_some_word_anymore].grep(/some_word/)
# => ["some_word", "not_some_word_anymore"]

如果要在正则表达式中使用变量/参数some_word,则必须以某种方式替换它。一个简单的方法是:

/#{ some_word }/

或:

Regexp.new( some_word )

例如:

foo = 'some_word'
/#{ foo }/      # => /some_word/
Regexp.new(foo) # => /some_word/

原因:

["foo", "bar", "baz", "quax"].each do |some_word|
end

返回相同的数组,这就是each的行为方式。我们通常不在乎。如果要转换该数组,请使用map

["foo", "bar", "baz", "quax"].map { |some_word| some_word.size }
# => [3, 3, 3, 4]

如果您尝试减少数组,请使用grepselectreject

["foo", "bar", "baz", "quax"].reject { |some_word| some_word['oo'] }
# => ["bar", "baz", "quax"]

["foo", "bar", "baz", "quax"].select { |some_word| some_word['oo'] }
# => ["foo"]