ruby puzzle: Group candies by unique record fields

Discussion in 'Ruby' started by Woga Swoga, Dec 19, 2006.

  1. Woga Swoga

    Woga Swoga Guest

    I have an list of objects (Candy) and each object has two fields
    (Candy.color, Candy.taste). I would like to display the candies but
    group them based on the fields (display a header for each group). The
    problem is I don't know how many colors or tastes are in any particular
    list of candies.

    This is what I have for input:

    * Candy <-- hash list already pre-sorted by "group"
    * group <-- variable contains either "color" or "taste"

    Can anyone come up with a ruby code snipet that will use the "group"
    variable to extract out the group labels (unique values of the color or
    tate field), and then dump out the Candy list by group.

    Really appreciate your help!

    --
    Posted via http://www.ruby-forum.com/.
     
    Woga Swoga, Dec 19, 2006
    #1
    1. Advertising

  2. Woga Swoga

    Brad Phelan Guest

    Woga Swoga wrote:
    > I have an list of objects (Candy) and each object has two fields
    > (Candy.color, Candy.taste). I would like to display the candies but
    > group them based on the fields (display a header for each group). The
    > problem is I don't know how many colors or tastes are in any particular
    > list of candies.
    >
    > This is what I have for input:
    >
    > * Candy <-- hash list already pre-sorted by "group"
    > * group <-- variable contains either "color" or "taste"
    >
    > Can anyone come up with a ruby code snipet that will use the "group"
    > variable to extract out the group labels (unique values of the color or
    > tate field), and then dump out the Candy list by group.
    >
    > Really appreciate your help!
    >


    require 'yaml'

    @candies = [
    { :name => 'a', :color => "blue", :taste => "good" },
    { :name => 'b',:color => "blue", :taste => "yuck" },
    { :name => 'c',:color => "red", :taste => "ok" },
    { :name => 'd',:color => "blue", :taste => "yuck" },
    { :name => 'e',:color => "green", :taste => "good" },
    { :name => 'f',:color => "green", :taste => "yuck" }
    ]

    def print_candies_by(group)
    groups={}
    @candies.each do |candy|
    key = candy[group]
    groups[key] = [] unless groups[key]
    groups[key] << candy
    end

    puts "##########'"
    puts YAML.dump groups
    puts "##########'"
    end


    print_candies_by :taste
    print_candies_by :color

    ----------------
    ##########'
    ---
    good:
    - :taste: good
    :name: a
    :color: blue
    - :taste: good
    :name: e
    :color: green
    yuck:
    - :taste: yuck
    :name: b
    :color: blue
    - :taste: yuck
    :name: d
    :color: blue
    - :taste: yuck
    :name: f
    :color: green
    ok:
    - :taste: ok
    :name: c
    :color: red
    ##########'
    ##########'
    ---
    green:
    - :taste: good
    :name: e
    :color: green
    - :taste: yuck
    :name: f
    :color: green
    blue:
    - :taste: good
    :name: a
    :color: blue
    - :taste: yuck
    :name: b
    :color: blue
    - :taste: yuck
    :name: d
    :color: blue
    red:
    - :taste: ok
    :name: c
    :color: red
    ##########'


    --
    Brad Phelan
    http://xtargets.com
     
    Brad Phelan, Dec 19, 2006
    #2
    1. Advertising

  3. ruby soppourt a cron?

    can ruby have a cron for his can control?

    how i use ruby for create a system a control of user?

    2006/12/19, Brad Phelan <>:
    > Woga Swoga wrote:
    > > I have an list of objects (Candy) and each object has two fields
    > > (Candy.color, Candy.taste). I would like to display the candies but
    > > group them based on the fields (display a header for each group). The
    > > problem is I don't know how many colors or tastes are in any particular
    > > list of candies.
    > >
    > > This is what I have for input:
    > >
    > > * Candy <-- hash list already pre-sorted by "group"
    > > * group <-- variable contains either "color" or "taste"
    > >
    > > Can anyone come up with a ruby code snipet that will use the "group"
    > > variable to extract out the group labels (unique values of the color or
    > > tate field), and then dump out the Candy list by group.
    > >
    > > Really appreciate your help!
    > >

    >
    > require 'yaml'
    >
    > @candies = [
    > { :name => 'a', :color => "blue", :taste => "good" },
    > { :name => 'b',:color => "blue", :taste => "yuck" },
    > { :name => 'c',:color => "red", :taste => "ok" },
    > { :name => 'd',:color => "blue", :taste => "yuck" },
    > { :name => 'e',:color => "green", :taste => "good" },
    > { :name => 'f',:color => "green", :taste => "yuck" }
    > ]
    >
    > def print_candies_by(group)
    > groups={}
    > @candies.each do |candy|
    > key = candy[group]
    > groups[key] = [] unless groups[key]
    > groups[key] << candy
    > end
    >
    > puts "##########'"
    > puts YAML.dump groups
    > puts "##########'"
    > end
    >
    >
    > print_candies_by :taste
    > print_candies_by :color
    >
    > ----------------
    > ##########'
    > ---
    > good:
    > - :taste: good
    > :name: a
    > :color: blue
    > - :taste: good
    > :name: e
    > :color: green
    > yuck:
    > - :taste: yuck
    > :name: b
    > :color: blue
    > - :taste: yuck
    > :name: d
    > :color: blue
    > - :taste: yuck
    > :name: f
    > :color: green
    > ok:
    > - :taste: ok
    > :name: c
    > :color: red
    > ##########'
    > ##########'
    > ---
    > green:
    > - :taste: good
    > :name: e
    > :color: green
    > - :taste: yuck
    > :name: f
    > :color: green
    > blue:
    > - :taste: good
    > :name: a
    > :color: blue
    > - :taste: yuck
    > :name: b
    > :color: blue
    > - :taste: yuck
    > :name: d
    > :color: blue
    > red:
    > - :taste: ok
    > :name: c
    > :color: red
    > ##########'
    >
    >
    > --
    > Brad Phelan
    > http://xtargets.com
    >
    >
     
    juan pedro meriño, Dec 19, 2006
    #3
  4. On Dec 19, 2006, at 10:30 AM, Brad Phelan wrote:

    > Woga Swoga wrote:
    >> I have an list of objects (Candy) and each object has two fields
    >> (Candy.color, Candy.taste). I would like to display the candies but
    >> group them based on the fields (display a header for each group).
    >> The
    >> problem is I don't know how many colors or tastes are in any
    >> particular
    >> list of candies.
    >> This is what I have for input:
    >> * Candy <-- hash list already pre-sorted by "group"
    >> * group <-- variable contains either "color" or "taste"
    >> Can anyone come up with a ruby code snipet that will use the "group"
    >> variable to extract out the group labels (unique values of the
    >> color or
    >> tate field), and then dump out the Candy list by group.
    >> Really appreciate your help!

    >
    > require 'yaml'
    >
    > @candies = [
    > { :name => 'a', :color => "blue", :taste => "good" },
    > { :name => 'b',:color => "blue", :taste => "yuck" },
    > { :name => 'c',:color => "red", :taste => "ok" },
    > { :name => 'd',:color => "blue", :taste => "yuck" },
    > { :name => 'e',:color => "green", :taste => "good" },
    > { :name => 'f',:color => "green", :taste => "yuck" }
    > ]
    >
    > def print_candies_by(group)
    > groups={}
    > @candies.each do |candy|
    > key = candy[group]
    > groups[key] = [] unless groups[key]
    > groups[key] << candy
    > end
    >
    > puts "##########'"
    > puts YAML.dump groups
    > puts "##########'"
    > end
    >
    >
    > print_candies_by :taste
    > print_candies_by :color


    You can also use sets for this:

    >> require "set"

    => true
    >> candies = [

    ?> { :name => 'a', :color => "blue", :taste => "good" },
    ?> { :name => 'b',:color => "blue", :taste => "yuck" },
    ?> { :name => 'c',:color => "red", :taste => "ok" },
    ?> { :name => 'd',:color => "blue", :taste => "yuck" },
    ?> { :name => 'e',:color => "green", :taste => "good" },
    ?> { :name => 'f',:color => "green", :taste => "yuck" }
    >> ]

    => [{:color=>"blue", :taste=>"good", :name=>"a"},
    {:color=>"blue", :taste=>"yuck", :name=>"b"},
    {:color=>"red", :taste=>"ok", :name=>"c"},
    {:color=>"blue", :taste=>"yuck", :name=>"d"},
    {:color=>"green", :taste=>"good", :name=>"e"},
    {:color=>"green", :taste=>"yuck", :name=>"f"}]
    >> candies.to_set.classify { |c| c[:color] }

    => {"green"=>#<Set: {{:color=>"green", :taste=>"yuck", :name=>"f"},
    {:color=>"green", :taste=>"good", :name=>"e"}}>, "blue"=>#<Set:
    {{:color=>"blue", :taste=>"good", :name=>"a"},
    {:color=>"blue", :taste=>"yuck", :name=>"d"},
    {:color=>"blue", :taste=>"yuck", :name=>"b"}}>, "red"=>#<Set:
    {{:color=>"red", :taste=>"ok", :name=>"c"}}>}

    James Edward Gray II
     
    James Edward Gray II, Dec 19, 2006
    #4
  5. Brad Phelan wrote:
    > Woga Swoga wrote:
    > > I have an list of objects (Candy) and each object has two fields
    > > (Candy.color, Candy.taste). I would like to display the candies but
    > > group them based on the fields (display a header for each group). The
    > > problem is I don't know how many colors or tastes are in any particular
    > > list of candies.
    > >
    > > This is what I have for input:
    > >
    > > * Candy <-- hash list already pre-sorted by "group"
    > > * group <-- variable contains either "color" or "taste"
    > >
    > > Can anyone come up with a ruby code snipet that will use the "group"
    > > variable to extract out the group labels (unique values of the color or
    > > tate field), and then dump out the Candy list by group.
    > >
    > > Really appreciate your help!
    > >

    >
    > require 'yaml'
    >
    > @candies = [
    > { :name => 'a', :color => "blue", :taste => "good" },
    > { :name => 'b',:color => "blue", :taste => "yuck" },
    > { :name => 'c',:color => "red", :taste => "ok" },
    > { :name => 'd',:color => "blue", :taste => "yuck" },
    > { :name => 'e',:color => "green", :taste => "good" },
    > { :name => 'f',:color => "green", :taste => "yuck" }
    > ]
    >
    > def print_candies_by(group)
    > groups={}
    > @candies.each do |candy|
    > key = candy[group]
    > groups[key] = [] unless groups[key]
    > groups[key] << candy
    > end
    >
    > puts "##########'"
    > puts YAML.dump groups
    > puts "##########'"
    > end
    >
    >
    > print_candies_by :taste
    > print_candies_by :color
    >
    > ----------------
    > ##########'
    > ---
    > good:
    > - :taste: good
    > :name: a
    > :color: blue
    > - :taste: good
    > :name: e
    > :color: green
    > yuck:
    > - :taste: yuck
    > :name: b
    > :color: blue
    > - :taste: yuck
    > :name: d
    > :color: blue
    > - :taste: yuck
    > :name: f
    > :color: green
    > ok:
    > - :taste: ok
    > :name: c
    > :color: red
    > ##########'
    > ##########'
    > ---
    > green:
    > - :taste: good
    > :name: e
    > :color: green
    > - :taste: yuck
    > :name: f
    > :color: green
    > blue:
    > - :taste: good
    > :name: a
    > :color: blue
    > - :taste: yuck
    > :name: b
    > :color: blue
    > - :taste: yuck
    > :name: d
    > :color: blue
    > red:
    > - :taste: ok
    > :name: c
    > :color: red
    > ##########'



    $candies = [
    { :name => 'a', :color => "blue", :taste => "good" },
    { :name => 'b',:color => "blue", :taste => "yuck" },
    { :name => 'c',:color => "red", :taste => "ok" },
    { :name => 'd',:color => "blue", :taste => "yuck" },
    { :name => 'e',:color => "green", :taste => "good" },
    { :name => 'f',:color => "green", :taste => "yuck" }
    ]

    def print_candies_by property
    values = $candies.inject([]){|ary,hash| ary << hash[property] }.uniq
    values.sort.each{|val| puts val
    $candies.select{|h| h[property] == val}.each{|h|
    puts " " + h.to_a.reject{|k,v| k == property }.
    map{|k,v| "#{k}: #{v}"}.join( "; " ) }
    }
    end

    print_candies_by :color

    --- output -----
    blue
    name: a; taste: good
    name: b; taste: yuck
    name: d; taste: yuck
    green
    name: e; taste: good
    name: f; taste: yuck
    red
    name: c; taste: ok
     
    William James, Dec 19, 2006
    #5
  6. Woga Swoga

    Drew Olson Guest

    Woga Swoga wrote:

    > Can anyone come up with a ruby code snipet that will use the "group"
    > variable to extract out the group labels (unique values of the color or
    > tate field), and then dump out the Candy list by group.
    >
    > Really appreciate your help!


    Not sure if your Candy list is actually a hash or just an array of Candy
    objects. I'll write the code assuming the later.

    group_flag = false
    group_flag = true if group == "color"
    grouping = {}

    candy.each do |piece|
    element = piece.color if group_flag
    element = piece.taste if !group_flag
    grouping[element] ||= []
    grouping[element] << piece
    end

    grouping.each do |key,element|
    puts "Grouping: #{key}"
    element.each do |piece|
    puts " "+candy.name
    end
    end

    --
    Posted via http://www.ruby-forum.com/.
     
    Drew Olson, Dec 20, 2006
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Glyn Williams

    Getting Unique ID from new record

    Glyn Williams, Mar 2, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    419
    =?Utf-8?B?U3VyZXNo?=
    Mar 2, 2004
  2. Two candies

    , Jan 2, 2008, in forum: Python
    Replies:
    6
    Views:
    441
  3. ToshiBoy
    Replies:
    6
    Views:
    857
    ToshiBoy
    Aug 12, 2008
  4. Replies:
    0
    Views:
    416
  5. Token Type
    Replies:
    9
    Views:
    364
    Chris Angelico
    Sep 9, 2012
Loading...

Share This Page