过滤哈希数组以仅保留其哈希包含数组中包含的键的那些元素?
Filter an array of hashes to keep only those elements whose hashes contain a key contained in an array?
这里我们有一个哈希数组。我们如何才能只保留数组中至少包含一个键的哈希值?
# array of hashes
@arr_of_h = [{first: 10},
{second: 10, secondB: 10},
{third: 10, thirdB: 10}]
# array
arr = ["first", "third"]
期望的输出
@output = [{:first=>10}, {:third=>10, :thirdB=>10}]
使用 Array select 尝试以下操作:
select
will return an array containing elements which match the condition provided on the block.
希望数组每个索引的散列只包含一个键
@arr_of_h.select{ |element| arr.include?(element.keys.first.to_s) }
编辑#1
To find the record which at least has one key contained in an array
我们可以通过Array select和数组实现吗?
@arr_of_h.select{ |element| element.keys.any? {|element| arr.include?(element.to_s) }}
如果您的数组中有多个键的散列,并且如果散列键之一出现在 'keep' 数组中,您希望保留散列,这将起作用。
arr_of_h.delete_if { |hash| (arr & (hash.keys.map(&:to_s))).empty? }
正如 Cary 正确指出的那样,这确实会改变数组。如果您不想改变数组:
arr_of_h.select { |hash| (arr & (hash.keys.map(&:to_s))).any? }
如果速度很重要,并且数组有很多元素,这意味着需要多次查找,请使用 set
。此外,为了速度,在开始时将数组转换为符号,而不是在 select
循环中将其转换。请注意,对于 OP 描述的特定情况,速度改进即使有也很小,因为所有输入都很小。
require "Set"
@arr_of_h = [{first: 10}, {second: 10}, {third: 10}]
arr = ["first", "third"]
arr_as_set = arr.map(&:to_sym).to_set
@output = @arr_of_h.select { |h| arr_as_set.include?(h.keys.first) }
puts @output
# Prints:
# {:first=>10}
# {:third=>10}
另请参见:
Set#include?
docs
More on Set#include?
Speed comparisons for arrays, sets, and hashes, with benchmarks
这里我们有一个哈希数组。我们如何才能只保留数组中至少包含一个键的哈希值?
# array of hashes
@arr_of_h = [{first: 10},
{second: 10, secondB: 10},
{third: 10, thirdB: 10}]
# array
arr = ["first", "third"]
期望的输出
@output = [{:first=>10}, {:third=>10, :thirdB=>10}]
使用 Array select 尝试以下操作:
select
will return an array containing elements which match the condition provided on the block.
希望数组每个索引的散列只包含一个键
@arr_of_h.select{ |element| arr.include?(element.keys.first.to_s) }
编辑#1
To find the record which at least has one key contained in an array
我们可以通过Array select和数组实现吗?
@arr_of_h.select{ |element| element.keys.any? {|element| arr.include?(element.to_s) }}
如果您的数组中有多个键的散列,并且如果散列键之一出现在 'keep' 数组中,您希望保留散列,这将起作用。
arr_of_h.delete_if { |hash| (arr & (hash.keys.map(&:to_s))).empty? }
正如 Cary 正确指出的那样,这确实会改变数组。如果您不想改变数组:
arr_of_h.select { |hash| (arr & (hash.keys.map(&:to_s))).any? }
如果速度很重要,并且数组有很多元素,这意味着需要多次查找,请使用 set
。此外,为了速度,在开始时将数组转换为符号,而不是在 select
循环中将其转换。请注意,对于 OP 描述的特定情况,速度改进即使有也很小,因为所有输入都很小。
require "Set"
@arr_of_h = [{first: 10}, {second: 10}, {third: 10}]
arr = ["first", "third"]
arr_as_set = arr.map(&:to_sym).to_set
@output = @arr_of_h.select { |h| arr_as_set.include?(h.keys.first) }
puts @output
# Prints:
# {:first=>10}
# {:third=>10}
另请参见:
Set#include?
docs
More on Set#include?
Speed comparisons for arrays, sets, and hashes, with benchmarks