如何根据 ruby 中的属性从数组的数组中过滤出数组?

How to filterout the arrays from aray of an array based on an attribute in ruby?

我有一个数组,其中包含一些额外信息以及 ID,我想使用此 ID 从数组数组中过滤掉数组。下面是一个例子。

[[#<Position:0x00007fc32a124b80
   self_id: 1077,
   position_id: 5,
   person_id: 57,
   started_on: Thu, 01 Sep 2016,
   ended_on: nil,
   branch_id: 45,
   relevant_position: true],
[#<Position:0x00007fc32a1652c0
   self_id: 1732,
   position_id: 8,
   person_id: 3219156,
   started_on: Mon, 01 Feb 2021,
   ended_on: nil,
   branch_id: 45,
   relevant_position: true]]

所以,我想使用上面数组中的'person_id'(57和3219156)来过滤掉下面给出的数组

[#<Person:0x00007fc32909a058
   id: 57,
   nationality_id: 2,
   title_id: 1,
   company_id: 44974,
   gender_id: 3,
   marital_status_id: 4,
   partner_id: nil>,
#<Person:0x00007fc329098488
  id: 3219156,
  nationality_id: 1,
  title_id: 1,
  company_id: 44974,
  gender_id: 3,
  marital_status_id: 1,
  partner_id: nil>,
#<Person:0x00007fc329098488
 id: 3106438,
 nationality_id: 1,
 title_id: 1,
 company_id: 44974,
 gender_id: 3,
 marital_status_id: 1,
 partner_id: nil>]

在第二个数组中,我们有带有 'ids' 的数组,所以我希望过滤掉那些数组,其中第一个数组中的 'person_id' 不存在于该元素的 'id' 中第二个数组。在这种情况下,应过滤掉第二个数组的最后一个元素,因为它的 'id' 不存在于第一个数组的 'person_id'.

当然有更好的方法可以用 Rails 或任何数据库来完成这种事情,但您似乎需要 pure-Ruby 方法,所以这里有一些选择。

选项 1:

filtered_array = people_array.filter do |person|
    positions_array.find{|pos| pos.person_id == person.id}
end.to_a

#filter 将 return 一个仅包含 return 块中 'truthy' 值的元素的数组。因为 #find 将 return person 元素本身(考虑 'truthy')如果它符合条件或 nil(不考虑 'truty')如果元素不发现这满足了您想要的块和过滤器。

注意块后的 #to_a#filter returns 和枚举数,不是数组所以你需要转换它。当然,如果适合您,您可以只使用惰性形式的枚举器而不是构建数组。

选项 2:

people_ids = positions_array.map(&:person_id).sort.uniq

filtered_array = people_array.filter do |person|
    people_ids.include?(person.id)
end.to_a

在这里,我们根据位置构建人员 ID 数组,并使用 #uniq 排序并删除重复项,然后通过调用 Array#include? 过滤人员数组以查看该人员的 ID 是否存在于数组中我们想要的 ID。

此选项在某些情况下可能表现更好。

此外,关于 positions_array.map(&:person_id) 行。如果你还没有看到这个语法之前它只是 shorthand 为这个:positions_array.map{|pos| pos.person_id }.

同样,仅当您打算不使用 Rails 或数据库时才执行此操作。但希望这里有一些 Ruby 经验教训可能对其他地方有价值。

如果您使用的是 Rails,您可以了解关联来处理此类问题。在此处查看教程: https://guides.rubyonrails.org/association_basics.html