你做比做比較散列結構更多。您正在以非常特定的方式(子集)比較結構。您還正在檢查實際值的有效性。這是很多卸載到Hash
。如果你有master_table
的任何槓桿作用,我會提取一些實際的物體爲你做這項工作。
以下是對象的示例解決方案。
我開始通過創建一些驗證對象:
class KlassValidation
attr_reader :klass
def initialize(klass)
@klass = klass
end
def valid?(hash, key)
return true unless hash.keys.include?(key)
hash[key].is_a? klass
end
end
string_validation = KlassValidation.new(String)
object_validation = KlassValidation.new(Object)
integer_validation = KlassValidation.new(Integer)
class HashValidation
attr_reader :validations
def initialize(validations)
@validations = validations
end
def valid?(hash, key=nil)
hash_to_validate = key ? hash[key] : hash
return true unless hash_to_validate
return false if invalid_keys?(hash_to_validate)
validations.all? { |key, validation| validation.valid?(hash_to_validate, key) }
end
def invalid_keys?(hash)
(hash.keys - validations.keys).any?
end
end
然後master_table
使用這些對象:
master_table = HashValidation.new(a: string_validation, b: object_validation, c: HashValidation.new(nested_a: integer_validation, nested_b: integer_validation))
檢查散列的有效性是不只是一個將它傳遞給的valid?
方法的事master_table
。
test_cases = [
{ valid: true, value: {a: 'cool value' } },
{ valid: false, value: {bogus: 'cool value' } },
{ valid: false, value: {a: :symbol } },
{ valid: true, value: {a: 'cool value', c: {nested_b: 540} } },
{ valid: false, value: {a: 'cool value', c: {nested_b: :symbol} } },
{ valid: false, value: {a: 'cool value', c: {bogus: :symbol} } }
]
test_cases.each do |test_case|
if test_case[:valid] == master_table.valid?(test_case[:value])
puts "Good!"
else
puts ">>>#{test_case[:value]} was not #{test_case[:valid]}"
end
end
這些測試的結果是:
Good!
Good!
Good!
Good!
Good!
Good!
現在,如果它是你必須開始用的my_table
在你的問題的形式散的情況下,我還是會使用HashValidation
執行驗證。在這種情況下,您遇到的問題是將my_table
轉換爲HashValidation
對象 - 這是一個比您想要解決的問題更簡單的問題。
master_table_orig = {a: String, b: Object, c: { nested_a: Integer, nested_b: Integer} }
def create_hash_validation(hash)
hash.inject({}) do |acc, (key, value)|
acc[key] = if value.is_a?(Hash)
HashValidation.new(create_hash_validation(hash[key]))
else
KlassValidation.new(value)
end
acc
end
end
master_table = HashValidation.new(create_hash_validation(master_table_orig))
使用驗證類的一個主要優點是您現在可以輕鬆地擴展您的解決方案。例如,在驗證中添加一個「必需的」選項會很簡單,如HashValidation.new(id: KlassValidation.new(Integer, required: true))
。
那麼,這裏有什麼問題? –
你究竟想要完成什麼?如果這不僅僅是一個編碼練習,我會重新評估'master_table'是否最好用散列表示,或者更適合作爲知道如何驗證散列的實際對象('my_table')。 –