【问题标题】:Comparing a hash of arrays to an array to find similarities将数组的哈希与数组进行比较以发现相似之处
【发布时间】:2016-09-18 03:10:59
【问题描述】:

我正在尝试将选定的animal_id 数组与owners_to_animals 数组中的“animal_id”对象进行比较,这样我就可以得到一个仅包含相关owner_id 的列表。我尝试遍历哈希,然后只选择在 animal_id 数组中匹配的 animal_id 对象,但它打印出不属于 animal_id 数组的 animal_id=20。

animal_id = [23, 53, 63]
owners_to_animals = [
  { "owner_id" => 73, "animal_id" => 53 },
  { "owner_id" => 73, "animal_id" => 23 },
  { "owner_id" => 73, "animal_id" => 63 },
  { "owner_id" => 73, "animal_id" => 20 },
  { "owner_id" => 83, "animal_id" => 23 },
  { "owner_id" => 83, "animal_id" => 63 }
]

owners_to_animals.each do |x|
  # puts x
  # x.each do |y|
  for i in animal_id do
    # puts i
    if x.select { |a| a["animal_id"] == i }
      puts x
    else
      puts "no"
    end
  end

  # end

end

我对 x 为什么返回感到困惑:

{"owner_id"=>73, "animal_id"=>53}
{"owner_id"=>73, "animal_id"=>53}
{"owner_id"=>73, "animal_id"=>53}
{"owner_id"=>73, "animal_id"=>23}
{"owner_id"=>73, "animal_id"=>23}
{"owner_id"=>73, "animal_id"=>23}
{"owner_id"=>73, "animal_id"=>63}
{"owner_id"=>73, "animal_id"=>63}
{"owner_id"=>73, "animal_id"=>63}
{"owner_id"=>73, "animal_id"=>20}
{"owner_id"=>73, "animal_id"=>20}
{"owner_id"=>73, "animal_id"=>20}
{"owner_id"=>83, "animal_id"=>23}
{"owner_id"=>83, "animal_id"=>23}
{"owner_id"=>83, "animal_id"=>23}
{"owner_id"=>83, "animal_id"=>63}
{"owner_id"=>83, "animal_id"=>63}
{"owner_id"=>83, "animal_id"=>63}

【问题讨论】:

  • 我编辑了您的代码以进行格式化,还使 owners_to_animals 成为一个显式数组,因为您的原始代码有些混乱。
  • owners_to_animals.select { |o_a| animal_id.include? o_a['animal_id'] }
  • @mudasobwa 这正是我在您发表评论前 3 小时发布的答案;)

标签: ruby multidimensional-array associative-array


【解决方案1】:

select 将在没有匹配项时返回一个空数组,这在 Ruby 中是一个“真实”值,因此您的代码的 else 分支永远不会被执行。

if []
  puts "true"
else
  puts "false"
end
# Outputs "true"

您想要实现的目标可以在一行中完成:

puts owners_to_animals.select { |x| animal_id.include?(x["animal_id"]) }
# Output:
{"owner_id"=>73, "animal_id"=>53}
{"owner_id"=>73, "animal_id"=>23}
{"owner_id"=>73, "animal_id"=>63}
{"owner_id"=>83, "animal_id"=>23}
{"owner_id"=>83, "animal_id"=>63}

【讨论】:

  • 在数组animal_id 和/或owners_to_animals 很大的类似情况下,建议先将前者转换为一个集合:require 'set'; animal_id_set = animal_id.to_set; owners_to_animals.select { |x| animal_id_set.include?(x["animal_id"]) }。与遍历数组相比,集合查找非常快,这是针对owners_to_animals 的每个元素(哈希)完成的。
  • @CarySwoveland 转换设置是否会产生差异?
  • 这是一个相对较小的一次性成本(基本上将数组转换为哈希,其中数组元素作为键,nil 作为 O(1) 查找的值),而不是 O(n ) 每次查找,如果 animal_id 很大,这可能会出现问题。
猜你喜欢
  • 1970-01-01
  • 2019-03-03
  • 2012-10-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-06
  • 2015-06-03
相关资源
最近更新 更多