从具有匹配键的散列数组中过滤掉散列

Filtering out hashes from arrays of hashes that have matching keys

假设我有一个这样的哈希数组

default_search_order = [
    { field: 'subscribers.nickname',   direction: 'ASC' },
    { field: 'subscribers.email',      direction: 'ASC' },
    { field: 'roles.name',             direction: 'ASC' },
    { field: 'subscribers.first_name', direction: 'ASC' }
]

我还有另一个哈希数组,由这样的查询提供:

order = [
    { :field => "subscribers.nickname",  :direction => "DESC"},
    { :field => "subscribers.email",     :direction => "DESC"},
    { :field => "subscribers.last_name", :direction => "DESC"}
]

我想从 default_search_order 中筛选出具有匹配字段值的哈希,然后像这样将两个哈希数组组合成一个哈希数组。

correct = [
    { field: "subscribers.nickname",   direction: "DESC"},
    { field: "subscribers.email",      direction: "DESC"},
    { field: "subscribers.last_name",  direction: "DESC"},
    { field: "roles.name",             direction: "ASC" },
    { field: "subscribers.first_name", direction: "ASC" }
]

我如何在 Rails 的 Ruby 中做到这一点?我一直在尝试#.delete_if?和#.keep_if?和#.select 但我在兜圈子。帮忙?

这是我的做法。第 1 步是按字段索引 default_search_order - 将其从数组转换为散列:

indexed = default_search_order.index_by { |hsh| hsh[:field] }

现在你的数据结构是这样的:

{
  'subscribers.nickname'   => { field: 'subscribers.nickname',   direction: 'ASC' },
  'subscribers.email'      => { field: 'subscribers.email',      direction: 'ASC' },
  'roles.name'             => { field: 'roles.name',             direction: 'ASC' },
  'subscribers.first_name' => { field: 'subscribers.first_name', direction: 'ASC' }
}

通过这样做,我们的工作变得简单了,因为我们可以立即知道第一个列表中的哪个条目对应于第二个给定的 field,并更新它(或者设置它,如果它尚不存在)。

order.each do |hsh|
  indexed[hsh[:field]] = hsh
end

最后,我们可以通过删除临时“索引”(哈希键)将其变回数组

results = indexed.values

另一种方法与第一种方法类似,但更加简洁:

[default_search_order, order]
  .map { |list| list.index_by { |hsh| hsh[:name] } }
  .reduce(&:merge)
  .values

另一种解决方案是合并 Arrays 并提取 unique

correct = (order + default_search_order).uniq { |f| f[:field] }
correct = order.push(*default_search_order).uniq { |f| f[:field] }

注意: 合并数组时变量顺序很重要,如果 default_search_order 写在 order 变量之前,那么结果会不同。