按多列对活动记录数组进行排序
Sort array of active records by multiple columns
给定一组活动记录
jobs = [#<Job _id: 1, created_at: 2014-07-15 19:18:40 UTC, organization: "Acme In.c">,
#<Job _id: 3, created_at: 2014-05-20 09:27:38 UTC, organization: "Baxter">,
#<Job _id: 2, created_at: 2014-11-25 12:21:00 UTC, organization: "Wizard">,
#<Job _id: 3, created_at: 2015-01-15 07:20:10 UTC, organization: "Baxter">]
如何先按 organization
升序 A->Z 对数组进行排序,然后按 created_at
降序对数组进行排序...
jobs = [#<Job _id: 1, created_at: 2014-07-15 19:18:40 UTC, organization: "Acme In.c">,
#<Job _id: 3, created_at: 2015-01-15 07:20:10 UTC, organization: "Baxter">,
#<Job _id: 3, created_at: 2014-05-20 09:27:38 UTC, organization: "Baxter">,
#<Job _id: 2, created_at: 2014-11-25 12:21:00 UTC, organization: "Wizard">]
我试过 jobs.sort_by{|j| [j.organization, j.created_at]}
但我不太确定如何指定多个 asc/desc 规则,我得到的最接近的是按组织排序,然后按创建排序让我从最老到最新,而不是从最新到最旧。我也试过先分组然后排序,但我也无法让它工作。任何帮助,如果赞赏。
一个好的方法是像这样使用 sort
and <=>
and nonzero?
:
jobs.sort{|a,b|
(a.organization <=> b.organization).nonzero? ||
(b.created_at <=> a.created_at)
}
这段代码表示:
- 按组织比较 A 和 B。
- 如果他们不同,那么我们就有了答案。
- 如果它们相同,那么我们需要做更多。
- 按时间比较B和A。 (注B&A顺序相反)
- 如果他们不同,那么我们就有了答案。
- 如果它们相同,则排序顺序无关紧要。 (Ruby 排序为 "unstable")
独立于 ActiveRecord 的示例代码:
require 'time'
require 'ostruct'
jobs = [
OpenStruct.new(_id: 1, created_at: Time.parse("2014-07-15 19:18:40 UTC"), organization: "Acme Inc"),
OpenStruct.new(_id: 3, created_at: Time.parse("2014-05-20 09:27:38 UTC"), organization: "Baxter"),
OpenStruct.new(_id: 2, created_at: Time.parse("2014-11-25 12:21:00 UTC"), organization: "Wizard"),
OpenStruct.new(_id: 3, created_at: Time.parse("2015-01-15 07:20:10 UTC"), organization: "Baxter")
]
如
所述
尝试jobs.order("organization ASC", "created_at DESC")
或以下
jobs.order("organization ASC").order("created_at DESC")
给定一组活动记录
jobs = [#<Job _id: 1, created_at: 2014-07-15 19:18:40 UTC, organization: "Acme In.c">,
#<Job _id: 3, created_at: 2014-05-20 09:27:38 UTC, organization: "Baxter">,
#<Job _id: 2, created_at: 2014-11-25 12:21:00 UTC, organization: "Wizard">,
#<Job _id: 3, created_at: 2015-01-15 07:20:10 UTC, organization: "Baxter">]
如何先按 organization
升序 A->Z 对数组进行排序,然后按 created_at
降序对数组进行排序...
jobs = [#<Job _id: 1, created_at: 2014-07-15 19:18:40 UTC, organization: "Acme In.c">,
#<Job _id: 3, created_at: 2015-01-15 07:20:10 UTC, organization: "Baxter">,
#<Job _id: 3, created_at: 2014-05-20 09:27:38 UTC, organization: "Baxter">,
#<Job _id: 2, created_at: 2014-11-25 12:21:00 UTC, organization: "Wizard">]
我试过 jobs.sort_by{|j| [j.organization, j.created_at]}
但我不太确定如何指定多个 asc/desc 规则,我得到的最接近的是按组织排序,然后按创建排序让我从最老到最新,而不是从最新到最旧。我也试过先分组然后排序,但我也无法让它工作。任何帮助,如果赞赏。
一个好的方法是像这样使用 sort
and <=>
and nonzero?
:
jobs.sort{|a,b|
(a.organization <=> b.organization).nonzero? ||
(b.created_at <=> a.created_at)
}
这段代码表示:
- 按组织比较 A 和 B。
- 如果他们不同,那么我们就有了答案。
- 如果它们相同,那么我们需要做更多。
- 按时间比较B和A。 (注B&A顺序相反)
- 如果他们不同,那么我们就有了答案。
- 如果它们相同,则排序顺序无关紧要。 (Ruby 排序为 "unstable")
独立于 ActiveRecord 的示例代码:
require 'time'
require 'ostruct'
jobs = [
OpenStruct.new(_id: 1, created_at: Time.parse("2014-07-15 19:18:40 UTC"), organization: "Acme Inc"),
OpenStruct.new(_id: 3, created_at: Time.parse("2014-05-20 09:27:38 UTC"), organization: "Baxter"),
OpenStruct.new(_id: 2, created_at: Time.parse("2014-11-25 12:21:00 UTC"), organization: "Wizard"),
OpenStruct.new(_id: 3, created_at: Time.parse("2015-01-15 07:20:10 UTC"), organization: "Baxter")
]
如
所述尝试jobs.order("organization ASC", "created_at DESC")
或以下
jobs.order("organization ASC").order("created_at DESC")