2014-11-03 211 views
0

我有散列数组(#1),看起来像这样:红宝石数组值串

data = [{"username"=>"Luck", "mail"=>"[email protected]", "active"=>0}] 

,我想用下面的哈希值的阵列来比较(#2):

test = [{"username"=>"Luck", "mail"=>"[email protected]", "active"=>"0"}] 

其中#1我从我的黄瓜场景(我最不希望出现的场景)中的mysql2(实际上是在数据库中) 和#2从数据库中获得的数据。

根据定义#2必须是#1,所以我遵循与此代码的子集:

data = data.to_set 
test = test.to_set 
assert test.subset?(data) 

的问题是在数据阵列的active值不为一个字符串。在data的情况下,是Fixnum,在test的情况下,是String

我需要一个解决方案,即使对于数组中的多个散列也可以工作。 (由于数据库可以返回结果的多行)这就是为什么我转换成集,并使用subset?

从我得到了其他问题:

data.each do |obj| 
    obj.map do |k, v| 
    {k => v.to_s} 
    end 
end 

然而,它没有为我工作。有任何想法吗?

假设你可以做:

  • 所有data键将永远是字符串。
  • test中的所有键将始终为字符串。并始终与data相同。
  • test中的所有值将始终为字符串。
+0

是什么,如果该类型不是一个字符串?你能用它显示的数据类型更新你的例子吗?你的目标是能够说数据==测试? 'subset'从哪里来? – Anthony 2014-11-03 00:11:20

+0

更正了这个问题,以提供您正在讨论的答案。但对于初学者来说,获取数据==测试会很好。 – 2014-11-03 00:13:25

+0

'test'是'data'的子数组,当且仅当'(test-data).empty? => true'。那是你要的吗?请注意,如果'h'和'g'是散列,'h == g => true'当且仅当它们具有相同的键和值时,无论键顺序如何。 – 2014-11-03 00:41:41

回答

0

假设我正确地理解了这个问题,这里有几个方法应该这样做。

#1:转换的哈希值到字符串

def stringify_hash_values(h) 
    h.each_with_object({}) { |(k,v),h| h[k] = v.to_s } 
end 

def sorta_subset?(data,test) 
    (test.map { |h| stringify_hash_values(data) } - 
    data.map { |h| stringify_hash_values(data) }).empty? 
end 

data = [{"username"=>"Luck", "mail"=>"[email protected]", "active"=>0}] 
test = [{"username"=>"Luck", "mail"=>"[email protected]", "active"=>"0"}] 
sorta_subset?(data,test) #=> true 

#2是否键转换为字符串相同的和值相等

require 'set' 

def hashes_sorta_equal?(h,g) 
    hk = h.keys 
    (hk.to_set == g.keys.to_set) && 
    (h.values_at(*hk).map(&:to_s) == g.values_at(*hk).map(&:to_s)) 
end 

def sorta_subset?(data,test) 
    test.all? { |h| data.any? { |g| hashes_sorta_equal?(g,h) } } 
end 

sorta_subset?(data,test) #=> true 
0

不要问我为什么它的工作原理,但我找到了解决办法:

data.map! do |obj| 
    obj.each do |k, v| 
    obj[k] = "#{v}" 
    end 
end 

我认为这事做什么的数组和哈希函数改变物体本身,而不是创建改变了对象的副本。

+0

它的工作原理是将每个元素转换为字符串。在'data'数组中,'active'被映射到一个数字,而它被映射到'test'中的一个字符串。这导致比较失败。 – 2014-11-03 00:56:24

+0

这就是我期待的。我做到了,但是我不确定这段代码是如何完成这项工作的。 – 2014-11-03 01:06:20

+1

是的,转换值转换为字符串,这将允许你使用'数据 - test',但要小心意外的副作用。如果,例如,您创建一个方法'sorta_subset?(测试数据)',你必须认识到,'test'和'data'将在调用方法后'sorta_subset?'返回了变化。一般来说,最好不要改变(“变异”)这些数组。你也不能改变'dup'ed数组中的值。请参阅我的解决方案中的#1,以便在不更改'data'或'test'的情况下执行此操作。 – 2014-11-03 01:31:57