Ruby puzzle: Group candies by unique record fields

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 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

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/\.

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 <phelan@tttech.ttt>:

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

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

···

On Dec 19, 2006, at 10:30 AM, Brad Phelan wrote:

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