mirror of
https://github.com/Freika/dawarich.git
synced 2026-01-10 17:21:38 -05:00
56 lines
1.5 KiB
Ruby
56 lines
1.5 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class CountriesAndCities
|
|
def initialize(points)
|
|
@points = points
|
|
end
|
|
|
|
def call
|
|
grouped_records = group_points
|
|
mapped_with_cities = map_with_cities(grouped_records)
|
|
filtered_cities = filter_cities(mapped_with_cities)
|
|
normalize_result(filtered_cities)
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :points
|
|
|
|
def group_points
|
|
points.group_by(&:country)
|
|
end
|
|
|
|
def map_with_cities(grouped_records)
|
|
grouped_records.transform_values do |grouped_points|
|
|
grouped_points
|
|
.pluck(:city, :timestamp) # Extract city and timestamp
|
|
.delete_if { _1.first.nil? } # Remove records without city
|
|
.group_by { |city, _| city } # Group by city
|
|
.transform_values do |cities|
|
|
{
|
|
points: cities.count,
|
|
last_timestamp: cities.map(&:last).max, # Get the maximum timestamp
|
|
stayed_for: ((cities.map(&:last).max - cities.map(&:last).min).to_i / 60) # Calculate the time stayed in minutes
|
|
}
|
|
end
|
|
end
|
|
end
|
|
|
|
def filter_cities(mapped_with_cities)
|
|
# Remove cities where user stayed for less than 1 hour
|
|
mapped_with_cities.transform_values do |cities|
|
|
cities.reject { |_, data| data[:stayed_for] < MIN_MINUTES_SPENT_IN_CITY }
|
|
end
|
|
end
|
|
|
|
def normalize_result(hash)
|
|
hash.map do |country, cities|
|
|
{
|
|
country:,
|
|
cities: cities.map do |city, data|
|
|
{ city:, points: data[:points], timestamp: data[:last_timestamp], stayed_for: data[:stayed_for] }
|
|
end
|
|
}
|
|
end
|
|
end
|
|
end
|