繁体   English   中英

Hash 具有 3 个不同的键,每个键指向一个实例数组。 如何按 id 对 arrays 进行排序?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM