简体   繁体   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?

I have a hash like so:我有一个 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

I will have a logged in user.我将有一个登录用户。 I am trying to organize the logged in user's availabilities by id.我正在尝试按 id 组织登录用户的可用性。

How do I sort each array by id.如何按 id 对每个数组进行排序。 I know if this was just an array I can do:我知道这是否只是我可以做的一个数组:

array.sort_by{|request| request.id}

But how do I iterate through each key's array?但是我如何遍历每个键的数组呢? I've tried multiple different ways and the only one that works is if I end up mapping over the hash and then another loop to sort the requests.我尝试了多种不同的方法,唯一可行的方法是,如果我最终映射到 hash 上,然后再使用另一个循环对请求进行排序。 But that doesn't return a hash.但这不会返回 hash。 Is there a way for me to keep the structure and sort it?有没有办法让我保持结构并对其进行排序?

The availabilities serializer is below:可用性序列化程序如下:

class RequestSerializer < ActiveModel::Serializer
  attributes :id, :start_time, :payment, :number_of_hours, :availability_id, :date, :name, :accept, :postcode, :phone_number
end

Below is one of the key, value pair outputs.下面是键值对输出之一。

: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>]

Thanks!谢谢!

result.transform_values { |array| array.sort_by(&:request_id) }

If the arrays are not not arrays of requests, but RequestSerializer , just call .object on them to get the request to sort by.如果 arrays 不是请求的 arrays ,而是RequestSerializer ,只需在它们上调用.object以获取请求排序依据。

result.transform_values do |array|
  array.sort_by { |serializer| serializer.object.request_id }
end

Another option would be to define request_id on RequestSerializer另一种选择是在RequestSerializer上定义request_id

You have to sort each hash value separately:您必须分别对每个 hash 值进行排序:

result.each_value { |array| array.sort_by!(&:id) }

Hash#each_value traverses the values and sort_by! Hash#each_value遍历值和sort_by! sorts the array in-place.就地对数组进行排序。

If you need to create a new sorted copy:如果您需要创建新的排序副本:

result.each_with_object({}) do |(key, value), list|
  list[key] = value.sort_by(&:id)
end

As Stefan posted in the comments.正如斯特凡在评论中发布的那样。 I can use a database query to order the requests prior to splitting them into their arrays.在将请求拆分为 arrays 之前,我可以使用数据库查询对请求进行排序。

The answer that worked (without doing multiple loops) was:有效的答案(不做多个循环)是:

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

Simply by removing self.只需删除自我。 and using the.order query and the id attribute, everything comes out ordered!并使用 .order 查询和 id 属性,一切都是有序的!

Thanks Stefan!谢谢斯特凡! (and everyone else) (以及其他所有人)

(Others worked with multiple methods or loops but as I was using Rails, the query is the quickest and easiest). (其他人使用多种方法或循环,但当我使用 Rails 时,查询是最快和最简单的)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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