简短问题:当调用对象“a”的方法并将其传递给块时,我可以从该块中访问“a”吗?
示例:假设我有一个数组“单词”,我首先要从中删除所有“坏”单词(使用函数确定),然后找到剩下的单词中最常见的单词。我可以用两行来完成:
temp_words = words.reject{|w| word_is_bad(w)}
puts temp_words.max{|w| temp_words.count(w)}
但是,我希望避免创建一个名为“temp_words”的新变量,并在一行中执行所有操作,如下所示:
words.reject{|w| word_is_bad(w)}.max{|w| self.count(w)}
即使我相信我的意图很明确,代码也会失败,因为“self”并不是指在调用reject之后生成的临时数组,而是指程序的主对象。
答案 0 :(得分:3)
如果你想坚持自己的方式,你可以写:
words.reject{|w| word_is_bad(w)}.instance_eval{max_by{|w| count(w)}}
但更好,更受欢迎的方法是:
words.reject{|w| word_is_bad(w)}.group_by{|w| w}.max_by{|_, a| a.length}.first
答案 1 :(得分:3)
简短的回答是否定的,不是没有使用instance_eval或类似的东西。
你真的不需要链接块。总是可以这样写:
words.max_by {|w| word_is_bad(w) ? -1 : words.count(w) }
(旁注,我想你可能想要max_by而不是max)
如果您发现自己必须聪明地使用一个衬垫来表达您的逻辑,那么在类中封装您需要的内容可能是有意义的。考虑这个简单的例子:
class Words < Array
def self.is_bad(word)
foo
end
def good
reject {|w| Word.is_bad(w) }
end
end
这将允许你写:
words = Words.new(["foo", "bar", "baz"])
words.good.max_by {|word| words.count(word) }
更具表现力并回避问题。
更进一步:
def max_good
good.max_by {|word| count(word) }
end
你可以简单地写words.max_good