[英]Hash with 3 different keys each pointing to an array of instances. How do I sort the arrays by id?
我有一个 hash 像这样:
def my_requests
result = {
accepted: [],
rejected: [],
pending: [],
}
self.requests.each do |request|
serialized_request = RequestSerializer.new(request)
if request.accept == nil
result[:pending].push(serialized_request)
elsif request.accept
result[:accepted].push(serialized_request)
else
result[:rejected].push(serialized_request)
end
end
result
end
我将有一个登录用户。 我正在尝试按 id 组织登录用户的可用性。
如何按 id 对每个数组进行排序。 我知道这是否只是我可以做的一个数组:
array.sort_by{|request| request.id}
但是我如何遍历每个键的数组呢? 我尝试了多种不同的方法,唯一可行的方法是,如果我最终映射到 hash 上,然后再使用另一个循环对请求进行排序。 但这不会返回 hash。 有没有办法让我保持结构并对其进行排序?
可用性序列化程序如下:
class RequestSerializer < ActiveModel::Serializer
attributes :id, :start_time, :payment, :number_of_hours, :availability_id, :date, :name, :accept, :postcode, :phone_number
end
下面是键值对输出之一。
:rejected=>[#<RequestSerializer:0x00007fa416e168a8 @object=#<Request id: 64, payment: 200, number_of_hours: 20, accept: false, start_time: "2000-01-01 16:20:00", venue_id: 1, availability_id: 4, created_at: "2020-08-30 12:15:04", updated_at: "2020-08-30 12:15:52">, @instance_options={}, @root=nil, @scope=nil>, #<RequestSerializer:0x00007fa416e167b8 @object=#<Request id: 4, payment: 160, number_of_hours: 4, accept: false, start_time: "2000-01-01 16:15:00", venue_id: 2, availability_id: 5, created_at: "2020-06-17 21:19:07", updated_at: "2020-06-17 21:21:32">, @instance_options={}, @root=nil, @scope=nil>, #<RequestSerializer:0x00007fa416e166c8 @object=#<Request id: 71, payment: 100, number_of_hours: 1, accept: false, start_time: "2000-01-01 09:45:00", venue_id: 1, availability_id: 6, created_at: "2020-10-01 08:45:43", updated_at: "2020-10-01 08:46:04">, @instance_options={}, @root=nil, @scope=nil>, #<RequestSerializer:0x00007fa416e16560 @object=#<Request id: 66, payment: 30, number_of_hours: 3, accept: false, start_time: "2000-01-01 16:30:00", venue_id: 1, availability_id: 26, created_at: "2020-08-30 12:31:02", updated_at: "2020-08-30 12:32:10">, @instance_options={}, @root=nil, @scope=nil>, #<RequestSerializer:0x00007fa416e163f8 @object=#<Request id: 68, payment: 20, number_of_hours: 3, accept: false, start_time: "2000-01-01 12:00:00", venue_id: 1, availability_id: 28, created_at: "2020-09-01 08:17:26", updated_at: "2020-09-01 13:09:54">, @instance_options={}, @root=nil, @scope=nil>]
谢谢!
result.transform_values { |array| array.sort_by(&:request_id) }
如果 arrays 不是请求的 arrays ,而是RequestSerializer
,只需在它们上调用.object
以获取请求排序依据。
result.transform_values do |array|
array.sort_by { |serializer| serializer.object.request_id }
end
另一种选择是在RequestSerializer
上定义request_id
您必须分别对每个 hash 值进行排序:
result.each_value { |array| array.sort_by!(&:id) }
Hash#each_value
遍历值和sort_by!
就地对数组进行排序。
如果您需要创建新的排序副本:
result.each_with_object({}) do |(key, value), list|
list[key] = value.sort_by(&:id)
end
正如斯特凡在评论中发布的那样。 在将请求拆分为 arrays 之前,我可以使用数据库查询对请求进行排序。
有效的答案(不做多个循环)是:
def my_requests
result = {
accepted: [],
rejected: [],
pending: [],
}
requests.order(:id).each do |request|
serialized_request = RequestSerializer.new(request)
if request.accept == nil
result[:pending].push(serialized_request)
elsif request.accept
result[:accepted].push(serialized_request)
else
result[:rejected].push(serialized_request)
end
end
result
end
只需删除自我。 并使用 .order 查询和 id 属性,一切都是有序的!
谢谢斯特凡! (以及其他所有人)
(其他人使用多种方法或循环,但当我使用 Rails 时,查询是最快和最简单的)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.