我有一個array和一個hash,我想要實作的是根據陣列中的排序對hash (id每個哈希內的每個)進行排序,如果id (in hash)中不存在my_array,它們不應該被洗掉而只是在排序中被推倒。
my_array = [4, 2, 5, 3, 1]
hash = [
{"id" => 1, "field_name" => "foo"},
{"id" => 2, "field_name" => "bar"},
{"id" => 3, "field_name" => "abc"},
{"id" => 4, "field_name" => "zsh"},
{"id" => 5, "field_name" => "kql"},
{"id" => 6, "field_name" => "plo"},
{"id" => 7, "field_name" => "cde"}
]
需要的輸出
[
{"id" => 4, "field_name" => "zsh"},
{"id" => 2, "field_name" => "bar"},
{"id" => 5, "field_name" => "kql"},
{"id" => 3, "field_name" => "abc"},
{"id" => 1, "field_name" => "foo"},
{"id" => 6, "field_name" => "plo"},
{"id" => 7, "field_name" => "cde"}
]
感謝任何幫助,并提前感謝!
uj5u.com熱心網友回復:
my_array = [4, 7, 5, 3, 1]
arr = [
{"id" => 1, "field_name" => "foo"},
{"id" => 2, "field_name" => "bar"},
{"id" => 3, "field_name" => "abc"},
{"id" => 4, "field_name" => "zsh"},
{"id" => 5, "field_name" => "kql"},
{"id" => 6, "field_name" => "plo"},
{"id" => 7, "field_name" => "cde"}
]
請注意,我已經my_array從問題中給出的內容進行了更改,并將陣列重命名為更合適的名稱。
arr.sort_by.with_index do |h,i|
my_array.include?(h["id"]) ? [0, h["id"]] : [1,i]
end
#=> [{"id"=>1, "field_name"=>"foo"},
# {"id"=>3, "field_name"=>"abc"},
# {"id"=>4, "field_name"=>"zsh"},
# {"id"=>5, "field_name"=>"kql"},
# {"id"=>7, "field_name"=>"cde"},
# {"id"=>2, "field_name"=>"bar"},
# {"id"=>6, "field_name"=>"plo"}]
請參閱Enumerable#sort_by。該方法使用Array#<=>對元素進行排序。特別參見檔案中的第三段<=>。
下面我列出sort_by了arr.
{"id" => 1, "field_name" => "foo"} -> [0, 1]
{"id" => 2, "field_name" => "bar"} -> [1, 1]
{"id" => 3, "field_name" => "abc"} -> [0, 3]
{"id" => 4, "field_name" => "zsh"} -> [0, 4]
{"id" => 5, "field_name" => "kql"} -> [0, 5]
{"id" => 6, "field_name" => "plo"} -> [1, 5]
{"id" => 7, "field_name" => "cde"} -> [0, 7]
如果[type, x]是用于排序的陣列sort_by,它將把所有元素 for which 放在type 0那些 for which 之前type = 1。為了打破關系,它按 . 對元素進行排序x。因為type = 1,x是元素的索引,它使它們在最后保持有序。
uj5u.com熱心網友回復:
映射您的 ID 陣列以按順序選擇匹配的哈希
雖然可能有更優雅的方式來做到這一點,但我認為下面的解決方案非常清楚。它使用您的id元素陣列作為要映射的 Enumerable 物件,回傳匹配的 Hash 物件以及"id"迭代期間遇到的每個鍵的匹配值(如果找到),然后洗掉未找到匹配項的任何元素,例如回傳的 Array通過#map 回傳nil。
使用 Ruby 3.1.2:
id_order = [4, 2, 5, 3, 1]
array_of_hashes = [
{"id" => 1, "field_name" => "foo"},
{"id" => 2, "field_name" => "bar"},
{"id" => 3, "field_name" => "abc"},
{"id" => 4, "field_name" => "zsh"},
{"id" => 5, "field_name" => "kql"},
{"id" => 6, "field_name" => "plo"},
{"id" => 7, "field_name" => "cde"}
]
id_order.map { |id| array_of_hashes.detect { |h| h["id"] == id } }.compact
這會正確回傳第一個陣列中指定的排序結果:
#=>
[{"id"=>4, "field_name"=>"zsh"},
{"id"=>2, "field_name"=>"bar"},
{"id"=>5, "field_name"=>"kql"},
{"id"=>3, "field_name"=>"abc"},
{"id"=>1, "field_name"=>"foo"}]
請注意,它不會回傳 ID 的 Hash 物件,6或者7因為它們不存在于要搜索的 ID 陣列中。您可以調整#map 以將它們視為傳遞(盡管您沒有解釋它們應該如何或為什么出現在結果陣列的末尾)或將它們添加到要搜索的元素陣列中,這將是首選方法。但是,由于它們沒有在您的原始帖子中得到解決,如果沒有找到匹配的 ID,這實際上是正確的輸出。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/495321.html
下一篇:根據范圍對數字進行分類
