迭代数组以查找哈希值

时间:2015-03-22 23:55:02

标签: ruby arrays regex hash

我有两个数组。一个存储字符串name,另一个存储哈希值people。我想过滤people数组,找到一个与我的名字数组中的一个字符串完全匹配的哈希。因此,例如来自names John Doe John 将被视为匹配,因为两者都包含 John

names = ["John", "Jane"]

people = [{name: "John Doe"}, {name: "Bill Bradley"}]

我尝试使用select方法匹配两者,但它返回一个空数组?

people.select{|person| person["name"] == names.any?}

2 个答案:

答案 0 :(得分:0)

试试这个:

matches = people.select do |person|
  !(names & person[:name].split(' ')).empty?
end

p matches #=> [{:name=>"John Doe"}]

基本上,您首先将哈希值与property[:name].split(' ')分隔为单个词。结果将是['John', 'Doe']之类的数组。然后,使用&amp ;;检查这个新创建的数组是否具有名称数组的任何公共元素。运营商。因此,你得到names & property[:name].split(' ')。如果没有产生匹配,那么您将拥有一个不是您想要的空数组,因此!(非)运算符。如果它更直观,你也可以这样做:

matches = people.reject do |person|
  (names & person[:name].split(' ')).empty?
end

此外,如果您想获取散列本身而不是包含在数组中的散列(或散列,如果有多个结果),请将select替换为detect。< / p>

答案 1 :(得分:0)

这将是一种方式:

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"} 

接下来我创建一个临时变量,这样我们就不必为h[:name]传入块中的每个元素提供enum

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"不匹配{{ 1}},所以"Jane"会返回any?而可怜的约翰尼也不会被选中。

以类似的方式,John Doe被选中,Bill Bradley被送回家。