Matching lines

I'm really wracking my brain about this one though I bet there must be
some simple command I don't know which I'm missing.

I've got a file with a few lines:
1: Kevin 25 football cricket guitar
2: John 15 football karate
3: Fred 20 rugby painting

Via regular expressions I'm trying to do a few things here such as
counting how many hobbies people have and counting how many people have
the same hobby- its this last one in particular I can't figure out.

The only way I can think of is to split each line into a array (which in
turn is stored in a array) and then have dual loops checking the 1st
hobby from person 1 against the firsts of the others then against the
seconds of the other and all but...This really does require a mountain
of code and its proving very troublesome.

Is there some special command in ruby I'm missing which could help me to
do this quicker?

···

--
Posted via http://www.ruby-forum.com/.

See if this gives you some fresh ideas:

persons_hobbies = Hash.new
hobbies = Hash.new

DATA.each do |line|
   fields = line.split
   fields[3..-1].each do |hobby|
     (persons_hobbies[fields[1]] ||= Array.new) << hobby
     (hobbies[hobby] ||= Array.new) << fields[1]
   end
end

puts "=== Hobby Counts ==="
puts hobbies.map { |h, c| "#{h}: #{c.size}" }
puts "=== Personal Counts ==="
puts persons_hobbies.map { |n, c| "#{n}: #{c.size}" }

__END__
1: Kevin 25 football cricket guitar
2: John 15 football karate
3: Fred 20 rugby painting

Hope that helps.

James Edward Gray II

···

On Dec 15, 2006, at 6:12 PM, Just Maz wrote:

I've got a file with a few lines:
1: Kevin 25 football cricket guitar
2: John 15 football karate
3: Fred 20 rugby painting

Via regular expressions I'm trying to do a few things here such as
counting how many hobbies people have and counting how many people have
the same hobby- its this last one in particular I can't figure out.

Just Maz wrote:

I'm really wracking my brain about this one though I bet there must be
some simple command I don't know which I'm missing.

I've got a file with a few lines:
1: Kevin 25 football cricket guitar
2: John 15 football karate
3: Fred 20 rugby painting

Via regular expressions I'm trying to do a few things here such as
counting how many hobbies people have and counting how many people have
the same hobby- its this last one in particular I can't figure out.

The only way I can think of is to split each line into a array (which in
turn is stored in a array) and then have dual loops checking the 1st
hobby from person 1 against the firsts of the others then against the
seconds of the other and all but...This really does require a mountain
of code and its proving very troublesome.

Is there some special command in ruby I'm missing which could help me to
do this quicker?

--
Posted via http://www.ruby-forum.com/\.

hobbies = Hash.new{ }

ARGF.each{|line| n, name, age, *his_hobbies = line.split
  his_hobbies.each{|s| hobbies[s] += [ name ] } }

hobbies.sort_by{|k,v| [ -v.size, k] }.each{|k,v|
  printf "%-10s%s\n", k, v.join(", ") }

Just Maz:

I've got a file with a few lines:
1: Kevin 25 football cricket guitar
2: John 15 football karate
3: Fred 20 rugby painting

Via regular expressions I'm trying to do a few things here such as
counting how many hobbies people have and counting how many people have
the same hobby- its this last one in particular I can't figure out.

Person = Struct.new(:name, :age, :hobbies)
data = readlines.
  map { |line| line.scan(/^\d+: (\w+) (\d+) (.*?)\s*$/).flatten }.
  map { |name, age, hobbies| Person.new(name, age.to_i, hobbies.split) }

# What hobbies does Kevin have?
p data.find { |p| p.name == 'Kevin' }.hobbies

# How many people like football?
p data.find_all { |p| p.hobbies.include? 'football' }.size

···

---

Further reading, if you use the methods above: ri Enumerable

Kalman

hobbies being the list of hobbies of one person
and persons_hobbies being...list of people who have hobbies???

James Gray wrote:

···

On Dec 15, 2006, at 6:12 PM, Just Maz wrote:
persons_hobbies = Hash.new
hobbies = Hash.new

DATA.each do |line|
   fields = line.split
   fields[3..-1].each do |hobby|
     (persons_hobbies[fields[1]] ||= Array.new) << hobby
     (hobbies[hobby] ||= Array.new) << fields[1]
   end
end

puts "=== Hobby Counts ==="
puts hobbies.map { |h, c| "#{h}: #{c.size}" }

--
Posted via http://www.ruby-forum.com/\.

hobbies looks like: {"football" => ["Kevin", "John"], ...}
persons_hobbies looks like: {"John" => ["football", "karate"], ...}

Others have shown how to do it with just one data structure and some iteration though.

James Edward Gray II

···

On Dec 16, 2006, at 4:39 AM, Just Maz wrote:

hobbies being the list of hobbies of one person
and persons_hobbies being...list of people who have hobbies???