Skip to content

Instantly share code, notes, and snippets.

@serradura
Created February 23, 2023 17:22
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save serradura/0d9e5aa37b2a99fa266bbb4734d33e8c to your computer and use it in GitHub Desktop.
Save serradura/0d9e5aa37b2a99fa266bbb4734d33e8c to your computer and use it in GitHub Desktop.
Abstractions to filter an array of hashes in Ruby
class FactoryCollectionFilter
def initialize(config)
@config = config || {}
end
def call(filters: {}, data: [])
return data if filters.empty?
filters.reduce(data) do |filtered, (filter, value)|
filter_fn = @config[filter]
filter_fn ? filtered.filter(&filter_fn[value]) : filtered
end
end
end
CollectionFilter = FactoryCollectionFilter.new(
'schedule.all_day_eq': ->(value, hash) { hash.dig(:schedule, :all_day) == value },
numbers_cont: ->(value, hash) { Array(hash[:numbers])&.include?(value) }
)
data = [
{
id: 1,
schedule: {all_day: true},
numbers: ['1', '2']
},
{
id: 2,
schedule: {all_day: false},
numbers: ['3', '4']
},
]
filters = { 'schedule.all_day_eq': false, numbers_cont: '3' }
CollectionFilter.call(filters: filters, data: data)
data = [
{
id: 1,
schedule: {all_day: true},
numbers: ['1', '2']
},
{
id: 2,
schedule: {all_day: false},
numbers: ['3', '4']
},
]
schedule_all_day = ->(hash) { hash.dig(:schedule, :all_day) }
numbers_contains = ->(number, hash) { hash[:numbers]&.include?(number) }.curry
data
.filter(&schedule_all_day)
.filter(&numbers_contains['1'])
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment