0

I want to construct a hash, the problem is that I have some customers that are buyers and others that are sellers that can have the same name and I need to group them in a hash by name. Something like this:

customers = {"name1": {"buyers": [id11,..,id1n], "sellers": [ids1,..,ids1n]},
             "name2": {"buyers": [id2,..,id], "sellers": [id1,..,idn] }}

The name is the key and the value is the hash with buyers and sellers, but I don't know how to initialize the hash and how to add a new key, value. Suppose that I have the Customer.all and I can for example ask:

Customer.all do |customer|
  if customer.buyer?
    puts customer.name, customer.id
  end
end
2
  • Could you edit the question to include an example of the input here please? Commented Jun 21, 2018 at 15:38
  • can you show an example of how you get the names from the db and also how you know who is a buyer and seller Commented Jun 21, 2018 at 15:38

2 Answers 2

2

You can use the block form of Hash.new to set up each hash key that does not have a corresponding entry, yet, to have a hash as its value with the 2 keys you need:

customers = Hash.new do |hash, key|
  hash[key] = { buyers: [], sellers: [] }
end

and then you can loop through and assign to either the :buyers or :sellers subarray as needed:

Customer.all do |customer|
  group = customers[customer.name] # this creates a sub hash if this is the first
                                   # time the name is seen
  group = customer.buyer? ? group[:buyers] : group[:sellers]

  group << customer.id
end

p customers
# Sample Output (with newlines added for readability):
# {"Customer Group 1"=>{:buyers=>[5, 9, 17], :sellers=>[1, 13]},
#  "Customer Group 2"=>{:buyers=>[6, 10], :sellers=>[2, 14, 18]},
#  "Customer Group 3"=>{:buyers=>[7, 11, 15], :sellers=>[3, 19]},
#  "Customer Group 0"=>{:buyers=>[20], :sellers=>[4, 8, 12, 16]}}

For those following along at home, this is the Customer class I used for testing:

class Customer
  def self.all(&block)
    1.upto(20).map do |id|
      Customer.new(id, "Customer Group #{id % 4}", rand < 0.5)
    end.each(&block)
  end

  attr_reader :id, :name
  def initialize(id, name, buyer)
    @id = id
    @name = name
    @buyer = buyer
  end

  def buyer?
    @buyer
  end
end
Sign up to request clarification or add additional context in comments.

Comments

0

Solution:

hsh = {}
Customer.all do |customer|
 if customer.buyer?
    hsh[customer.id] = customer.name
end
puts hsh

Pls, refer the following link to know more about Hash and nested Hash

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.