簡體   English   中英

基於某些元素中可能為零的屬性對數組進行排序

[英]Sorting an array based on an attribute that may be nil in some elements

我有一個對象數組

[<#a star=1  val=1>, <#a star=nil val=3> , <#a star=2  val=2>]

我需要按時間排序數組,然后按val排序

[ <#a star=2  val=2>, <#a star=1  val=1>, <#a star=nil val=3> ]

但是使用sort_by會拋出錯誤,因為時間是零。

我現在用一種丑陋的方式來排序,但我確信有一個很好的方法可以解決它

starred=[]
@answers.each {|a| (starred << a) if a.starred }
@answers=@answers-starred
starred=starred.sort_by {|a| a.starred }.reverse
@answers=starred+@answers
starred.sort_by { |a| [a ? 1 : 0, a] }

當必須比較兩個元素時,它會比較一個數組。 當Ruby比較數組(調用===方法)時,它會比較第一個元素,只有當第一個元素相等時才會轉到第二個元素。 ? 1 : 0 ? 1 : 0保證,我們將Fixnum作為第一個元素,所以它應該沒有錯誤。

如果你這樣做? 0 : 1 ? 0 : 1nil將出現在數組的末尾而不是開始。
這是一個例子:

irb> [2, 5, 1, nil, 7, 3, nil, nil, 4, 6].sort_by { |i| [i ? 1 : 0, i] }
=> [nil, nil, nil, 1, 2, 3, 4, 5, 6, 7]

irb> [2, 5, 1, nil, 7, 3, nil, nil, 4, 6].sort_by { |i| [i ? 0 : 1, i] }
=> [1, 2, 3, 4, 5, 6, 7, nil, nil, nil]

如果你想讓nils首先出現(零等價):

@answers.sort_by { |a| a.star or 0 }

如果你想讓它們顯示在最后,你可以用Max Int替換零,但這感覺太hacky。 這可能更好:

@answers.select(&:starred?).sort_by(&:star) + @answers.reject(&:starred?)

Nakilon提供的答案非常棒,盡管你基本上是在兩個不同的屬性上進行了兩次排序。 在大多數情況下,這可能就足夠了。

只需使用value.to_i

starred.sort_by { |a| a.to_i }.reverse

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM