所以,我有一個哈希陣列,讓我們以此為例
arr = [
{:series=>"GOT", :rating=>"Good", :type=>"Fantasy"},
{:series=>"BB", :rating=>"Great", :type=>"Crime"},
{:series=>"E", :rating=>"Poor", :type=>"Drama"}
]
我正在嘗試遍歷這個陣列,以便我可以將每個成員與所有后續成員進行比較。
例如 Hash 1 與 Hash 2 和 Hash 3 比較,Hash 2 與 Hash 3 比較
我已經寫過的實際比較函式:
output = (data[X].keys & data[Y].keys).select { |k| data[X][k] == data[Y][k] }
X 將是當前陣列,Y 是我們要比較的下一個元素。
編輯
這是我到目前為止所得到的
for i in 0..data.length
for j in i..data.length
# puts data[j 1]
output = (data[j].keys & data[j 1].keys).select { |k| data[j][k] == data[j 1][k] }
puts data[j]
puts data[j 1]
puts output
end
puts "*****"
end
我想要的輸出是列印我們正在比較的散列和其他散列,以及它們共享值的鍵。
例如這個陣列:
{:series=>"GOT", :rating=>"Great", :type=>"Fantasy"}
{:series=>"BB", :rating=>"Great", :type=>"Crime"}
應該列印這個:
{:series=>"GOT", :rating=>"Great", :type=>"Fantasy"}
{:series=>"BB", :rating=>"Great", :type=>"Crime"}
rating
如果鍵為 nil,則不應進行比較。我認為這就是為什么我在運行上述代碼時也會收到此錯誤:
Traceback (most recent call last):
4: from match_users.rb:18:in `<main>'
3: from match_users.rb:18:in `each'
2: from match_users.rb:19:in `block in <main>'
1: from match_users.rb:19:in `each'
match_users.rb:21:in `block (2 levels) in <main>': undefined method `keys' for nil:NilClass (NoMethodError)
uj5u.com熱心網友回復:
請注意,您沒有在回圈中使用“i”,這看起來像一個錯誤。此外,您的索引“j 1”超出了陣列的末尾,導致訪問 nil 元素。實際上,即使是“j”也會超出陣列的末尾。陣列從 0...length-1 訪問,而 "0..data.length" 將訪問 index 處的元素data.length。我猜你的意思更像是:
for i in 0..data.length-2
for j in i 1..data.length-1
output = (data[i].keys & data[j].keys).select { |k| data[i][k] == data[j][k] }
end
end
uj5u.com熱心網友回復:
創建一個可迭代的集合
首先,您發布的資料不是有效的 Ruby 哈希陣列;它只是一個 Hash 物件的順序串列,因此您無法對其進行迭代。您需要首先將 Hash 物件包裝成可迭代的物件,例如陣列。這是一個例子:
titles =
[{:series=>"GOT", :rating=>"Good", :type=>"Fantasy"},
{:series=>"BB", :rating=>"Great", :type=>"Crime"},
{:series=>"E", :rating=>"Poor", :type=>"Drama"}]
連續元素的相對比較
現在您有了一個可迭代的集合,您可以使用Enumerable#each_cons(它已經混合到 Ruby 核心中的 Array 中)來迭代每個順序的 Hash 物件對。出于演示目的,我選擇將相對比較作為陣列的一部分存盤在每個標題中。例如,使用上面存盤在標題中的 Hash 物件陣列:
STAR_MAPPINGS = {'great' => 5, 'good' => 4, 'fair' => 2,
'poor' => 1, 'unwatchable' => 0}.freeze
COMPARISON_MAP = {
-1 => 'is worse than',
0 => 'the same as',
1 => 'is better than'
}.freeze
def compare_ratings_for title_1, title_2
fmt = '_%s_ %s _%s_'
series_1, series_2 = title_1[:series], title_2[:series]
ratings_1, ratings_2 =
STAR_MAPPINGS[title_1[:rating].downcase],
STAR_MAPPINGS[title_2[:rating].downcase]
comparison_str = COMPARISON_MAP[ratings_1 <=> ratings_2]
format fmt, series_1, comparison_str, series_2
end
titles.each_cons(2).each do |h1, h2|
# Array#| return an ordered, deduplicated union of keys
matching_keys = (h1.keys | h2.keys).flatten.uniq
next if matching_keys.none?
# perform whatever comparisons you want here; this example
# compares ratings by assigning stars to each rating
h1[:comparisons] =
h1.fetch(:comparisons, []) << compare_ratings_for(h1, h2)
h2[:comparisons] =
h2.fetch(:comparisons, []) << compare_ratings_for(h2, h1)
end
titles
Titles變數現在保存并回傳以下資料:
[{:series=>"GOT", :rating=>"Good", :type=>"Fantasy", :comparisons=>["_GOT_ is worse than _BB_"]},
{:series=>"BB", :rating=>"Great", :type=>"Crime", :comparisons=>["_BB_ is better than _GOT_", "_BB_ is better than _E_"]},
{:series=>"E", :rating=>"Poor", :type=>"Drama", :comparisons=>["_E_ is worse than _BB_"]}]
這里又是相同的資料,但這次標題用Amazing_print漂亮地列印以提高可讀性:
[
{
:series => "GOT",
:rating => "Good",
:type => "Fantasy",
:comparisons => [
"_GOT_ is worse than _BB_"
]
},
{
:series => "BB",
:rating => "Great",
:type => "Crime",
:comparisons => [
"_BB_ is better than _GOT_",
"_BB_ is better than _E_"
]
},
{
:series => "E",
:rating => "Poor",
:type => "Drama",
:comparisons => [
"_E_ is worse than _BB_"
]
}
]
也可以看看
- 陣列#|
- 陣列#<=>
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/482713.html
上一篇:從陣列創建最小堆-2種方法
