2016-05-17 19 views
0

我試圖實現表格驗證算法,但是我對Ruby提供的用於處理數組和哈希值的多項選擇感到困惑,我需要幫助將它放在一起。以此表爲例:檢查表格中的單元格組合

| A | B | C | 
------------- 
| 1 | 2 | 3 | 
| 1 | 2 | 4 | 
| 5 | 6 | 7 | 
| 1 | 1 | 3 | 

我的方法應計算特定單元組合的出現次數。例如:

match_line([A => 1, C => 3]) 

結果應該2,因爲這兩者結合的第一行和最後一個存在。 我所做的到目前爲止是創建一個hash變量抱柱索引像這樣:

[A => 0, B => 1, C=> 2] 

而且我也有擁有上述所有錶行這樣一個數組列表:

[[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]] 

邏輯看起來像 - 上面的match_line方法特定的用戶想要匹配一行,其中列A的值爲1,列C的值爲3。基於我的索引散列,A列索引是0,C索引是2。現在對於數組列表中的每個數組(行),如果索引0等於1並且索引2等於3就像用戶請求的那樣,我向計數器添加+1並繼續檢查另一個數組行,直到我結束。

我試圖將它形成代碼,但我以一種看起來效率不高的方式結束了,我有興趣看到你的代碼示例看到Ruby可能有我不知道的內部Enumerable方法使其更加優雅。

回答

2

首先,你應該使用最好的結構來描述您的域:

data = [[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]] 

@data_hashes = data.map do |sequence| 
    { 'A' => sequence[0], 'B' => sequence[1], 'C' => sequence[2] } 
end 

其次,我認爲你應該使用一個真正的哈希作爲輸入match_line:

# replace match_line([A => 1, C => 3]) with 
match_line({'A' => 1, 'C' => 3}) 

現在你」使用Enumerable#selectArray#size(或使用如Keith Bennet指出的Array#count)使用Enumerable#selectArray#size

def match_line(match) 
    @data_hashes.count { |row| 
    match.all? { |match_key, match_value| 
     row[match_key] == match_value 
    } 
    } 
end 

編輯:動態地從列名

columns = ['a', 'b', 'c'] 
data = [[1, 2, 3], [1, 2, 4], [5, 6, 7], [1, 1, 3]] 

@data_hashes = data.map do |row| 
    Hash[columns.zip(row)] 
end 
+0

這的確使實現更容易,然後我的創建哈希值。我認爲我的錯誤是因爲你提到我的數據結構太複雜。上面的例子要求我的列是常量,但?如果表格列是動態選取的,這將不起作用?我猜我應該有另一個數組來保存列名,並以某種方式動態地對它進行序列化?謝謝! – Okiba

+0

方法應該很小並且尊重某種責任分離:定義一種方法來管理匹配,另一種方法根據輸入構建散列。這使得它更容易維護和重用。 – floum

+0

已經完成。它只是我不知道如何動態地分配鍵值到'@ data_hashes'?也許這樣的事情? 'column_names = ['d','e','f'] @data_hashes = data。map do | sequence | column_names.each_with_index do | value,index | {value => sequence [index]} end' – Okiba