# Matching lines

**URL:** <https://www.ruby-forum.com/t/matching-lines/79529>\
**Category:** Ruby\
**Created:** [December 16, 2006, 1:12am UTC](https://www.ruby-forum.com/t/matching-lines/79529 "2006-12-16T01:12:22Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 1:12am UTC](https://www.ruby-forum.com/t/matching-lines/79529/1 "2006-12-16T01:12:22Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 1:44am UTC](https://www.ruby-forum.com/t/matching-lines/79529/2 "2006-12-16T01:44:54Z")

</div>

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.

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 G. II

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 8:05am UTC](https://www.ruby-forum.com/t/matching-lines/79529/3 "2006-12-16T08:05:23Z")

</div>

Just Maz wrote:

> ## the same hobby- its this last one in particular I can’t figure out.
> 
> Posted via [http://www.ruby-forum.com/](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(", ") }

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 11:39am UTC](https://www.ruby-forum.com/t/matching-lines/79529/4 "2006-12-16T11:39:45Z")

</div>

hobbies being the list of hobbies of one person  
and persons\_hobbies being…list of people who have hobbies???

James G. 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}” }

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 2:05pm UTC](https://www.ruby-forum.com/t/matching-lines/79529/5 "2006-12-16T14:05:36Z")

</div>

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

---

<div class="post-metadata">

**Author:** ![maz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/e9c0ed/32.png) [@maz](https://www.ruby-forum.com/u/maz)\
**Post date:** [December 16, 2006, 5:13pm UTC](https://www.ruby-forum.com/t/matching-lines/79529/6 "2006-12-16T17:13:48Z")

</div>

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

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 G. II
