这是一种方式:
names = ["John", "Jane"]
people = [{name: "Johnny Jones"}, {name: "John Doe"}, {name: "Bill Bradley"}]
people.select { |h| hname = h[:name]; names.any? { |n| hname[/\b#{n}\b/i] } }
#=> [{:name=>"John Doe"}]
步骤:
enum = people.select
#=> #<Enumerator: [{:name=>"Johnny Jones"}, {:name=>"John Doe"},
# {:name=>"Bill Bradley"}]:select>
枚举器的第一个元素传入块中并赋值给块变量h:
h = enum.next
#=> {:name=>"Johnny Jones"}
接下来我创建一个临时变量,这样我们就不必为传递到块中的enum 的每个元素检索h[:name]:
hname = h[:name]
#=> "Johnny Jones"
然后查看names的任何元素是否匹配"Johnny Jones":
names.any? { |n| hname[/\b#{n}\b/i] }
#=> ["John", "Jane"].any? { |n| "Johnny Jones"[/\b#{n}\b/i] }
#=> false
在最后一个表达式中,"John" 被传递到块中并分配给块变量n。然后我们有:
"Johnny Jones"[/\bJohn\b/i]
#=> nil
第一个分词 (\b) 要求"John" 前面紧跟一个非单词字符(或者是字符串的第一个字符);第二个分词要求"John" 后面紧跟一个非单词字符(或者是字符串中的最后一个字符)。因此,"John" 不匹配 "Johnny Jones"。
names 的下一个(也是最后一个)元素("Jane" 然后被传递到块中并分配给n。"Johnny Jones" 也不匹配"Jane",所以any? 返回@987654345 @ 和可怜的约翰尼没有被选中。
以类似的方式,John Doe 被选中,Bill Bradley 被送回家。