简体   繁体   中英

Ruby array of hashes values to string

I have an array of hashes (#1) that looks like this:

data = [{"username"=>"Luck", "mail"=>"root@localhost.net", "active"=>0}]

that I am trying to compare with following array of hashes (#2):

test = [{"username"=>"Luck", "mail"=>"root@localhost.net", "active"=>"0"}]

where #1 I obtained from database by mysql2 (what actually is in the database) and #2 from my cucumber scenario (what I minimally expect ot be there).

By definition #2 must be a subset of #1 so I follow with this code:

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

The problem is in data array the value of active is NOT a string. In case of data it is Fixnum , and in case of test , it is String .

I need a solution that will work even for more than one hash in the array. (As the database can return more than one row of results) That is why I convert to sets and use subset?

From other questions I got:

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

However it does not work for me. Any ideas?

Assumptions you can make:

  • All the keys in data will always be Strings.
  • All the keys in test will always be Strings. And always be the identical to data .
  • All the values in test will always be Strings.

Don't ask me why it works, but I found A solution:

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

I think it has something to do with what functions on arrays and hashes change the object itself and not create a changed copy of the object.

Here are a couple of approaches that should do it, assuming I understand the question correctly.

#1: convert the hash values to strings

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"=>"root@localhost.net", "active"=>0}]
test = [{"username"=>"Luck", "mail"=>"root@localhost.net", "active"=>"0"}]
sorta_subset?(data,test) #=> true

#2 see if keys are the same and values converted to strings are equal

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM