tags:

views:

85

answers:

3

I have four arrays that are coming in from the client. Let's say that there is an array of names, birth dates, favorite color and location. The idea is I want a hash later where each name will have a hash with respective attributes:

Example date coming from the client:

[name0, name1, name2, name3]
[loc0, loc1]
[favcololor0, favcolor1]
[bd0, bd1, bd2, bd3, bd4, bd5]

Output I'd like to achieve:

name0 => { location => loc0, favcolor => favcolor0, bd => bd0 }
name1 => { location => loc1, favcolor => favcolor1, bd => bd1 }
name2 => { location => nil, favcolor => nil, bd => bd2 }
name3 => { location => nil, favcolor => nil, bd => bd3 }

I want to have an array at the end of the day where I can iterate and work on each particular person hash.

There need not be an equivalent number of values in each array. Meaning, names are required.. and I might receive 5 of them, but I only might receive 3 birth dates, 2 favorite colors and 1 location. Every missing value will result in a nil.

How does one make that kind of data structure with Ruby 1.9?

+2  A: 

I would probably do it like this

# assuming names, fav_colors, birth_dates, and locations are your arrays

name_collection = {}

names.zip(birth_dates, fav_colors, locations) do |name, birth_date, fav_color, location|
  name_collection[name] = { :birth_date => birth_date,
                            :fav_color => fav_color,
                            :location => location }
end

# usage
puts name_collection['jack'][:fav_color] # => 'blue'
Matt Briggs
A: 

A small class to represent a person

class Person
  attr_accessor :name, :color, :loc, :bd

  def initialize(args = {})
    @name = args[:name]
    @color = args[:color]
    @loc = args[:loc]
    @bd = args[:bd]
  end

  def pp()
    puts "*********"
    puts "Name: #{@name}"
    puts "Location: #{@loc}"
    puts "Birthday: #{@bd}"
    puts "Fav. Color: #{@color}"
    puts "*********"
  end
end

another to represent people, which is mainly just a listing of Persons.

class People
  attr_accessor :list_of_people

  def initialize()
    @list_of_people = {}
  end

  def load_people(names, locations, favcolors, birthdates)
    names.each_with_index do |name, index|
      @list_of_people[name] = Person.new(:name => name, :color => favcolors[index], :loc => locations[index], :bd => birthdates[index])
    end
  end

  def pp()
    @list_of_people.each_pair do |key, value|
      value.pp()
    end

  end
end

I threw in a pretty print function for each so you can see their data. With a starting point like this it will be really easy to modify and add methods that do all sorts of useful things.

if __FILE__ == $0
  names = ["name0", "name1", "name2", "name3"]
  locs = ["loc0","loc1"]
  favcolors = ["favcolor0", "favcolor1"]
  bds = ["bd0","bd1","bd2","bd3","bd4"]

  a = People.new()
  a.load_people(names,locs,favcolors,bds)
  a.pp()
end
Beanish
A: 

I think the kind of data structure you're looking for is -ahem- a Struct.

    # setup data
    names = %w(name0 name1 name2 name3)
    locations = %w(loc0 loc1)
    colors = %w(favcololor0 favcolor1)
    bd = %w(bd0 bd1 bd2 bd3 bd4 bd5)

    # let's go
    Person = Struct.new( :name, :location, :fav_color, :bd )
    all_persons = names.zip( locations, colors, bd ).map{|p| Person.new( *p)}
    # done

    puts all_persons
    someone= all_persons.find{|p| p.name == "name1"}
    puts someone.location unless someone.nil?
steenslag