簡體   English   中英

如何在不改變相同值ruby的位置的情況下以降序對哈希進行排序

[英]how to sort hash in descending order with out changing position of same value ruby

hash = {"p1"=>56, "p2"=>56, "p3"=>0, "p4"=>56, "p5"=>56, "p6"=>64, "p7"=>0}

p Hash[hash.sort_by{|k,v| v}.reverse] # gives 
{"p6"=>64, "p5"=>56, "p4"=>56, "p2"=>56, "p1"=>56, "p3"=>0}

但我想要輸出如下所示

{"p6"=>64, "p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56}

此外,最終哈希不需要密鑰為零。

p Hash[
  hash.reject { |_, v| v.zero? }.sort do |kv1, kv2| 
    (val = kv1.last <=> kv2.last).zero? ? kv2.first <=> kv1.first : val
  end.reverse]

#⇒ {"p6"=>64, "p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56}

UPD使用@CarySwoveland建議表示的塊變量並刪除多余的reverse

p Hash[
  hash.reject { |_, v| v.zero? }.sort do |(k1,v1), (k2,v2)| 
    (val = v2 <=> v1).zero? ? k1 <=> k2 : val
  end
]

#⇒ {"p6"=>64, "p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56}

注意 :上面將對相同值的鍵進行排序,而@ Cary的答案不會。

其他方式:

hash.reject { |_,v| v.zero? }
    .each_with_index
    .sort_by { |(_,v),i| [-v,i] }
    .map(&:first)
    .to_h
  #=> {"p6"=>64, "p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56} 

對於2.0之前的Ruby版本,將arr.to_h替換為Hash[arr]

步驟:

h = hash.reject { |_,v| v.zero? }
  #=> {"p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56, "p6"=>64} 
e = h.each_with_index
  #=> #<Enumerator: {"p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56,
  #                  "p6"=>64}:each_with_index> 
a = e.sort_by { |(_,v),i| [-v,i] }
  #=> [[["p6", 64], 4], [["p1", 56], 0], [["p2", 56], 1],
  #    [["p4", 56], 2], [["p5", 56], 3]]
b = a.map(&:first)
  #=> [["p6", 64], ["p1", 56], ["p2", 56], ["p4", 56], ["p5", 56]]
b.to_h
  #=> {"p6"=>64, "p1"=>56, "p2"=>56, "p4"=>56, "p5"=>56}

我們可以看到枚舉器e的值,它將通過將其轉換為數組傳遞給塊:

e.to_a
  #=> [[["p1", 56], 0], [["p2", 56], 1], [["p4", 56], 2],
  #    [["p5", 56], 3], [["p6", 64], 4]] 

編輯 :如果我誤解了這個問題(見下面的評論),@ mudasobwa的解釋是正確的,我的解決方案可以修改如下:

hash.reject { |_,v| v.zero? }.sort_by { |k,v| [-v,k] }.to_h

暫無
暫無

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

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