# Grouping similar attributes

**URL:** <https://www.ruby-forum.com/t/grouping-similar-attributes/84908>\
**Category:** Ruby\
**Created:** [February 8, 2007, 4:12pm UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908 "2007-02-08T16:12:40Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 8, 2007, 4:12pm UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/1 "2007-02-08T16:12:40Z")

</div>

How would one group attributes which came from an array/db?

For example in my DB:

* * *

## | NAME | ETHNIC |

## | Dominic | Asian |

## | John | Asian |

## | Rick | Spanish |

I’d like it to group by Ethnicity:

Asian

- Dominic
- John

Spanish

- Rich

Is there some ruby thing that makes this convenient?

Thanks a whole bunch.

Dominic

---

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 8, 2007, 4:56pm UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/2 "2007-02-08T16:56:34Z")

</div>

On Fri, Feb 09, 2007 at 12:12:42AM +0900, Dominic S. wrote:

> * * *
> 
> - Rich
> 
> Is there some ruby thing that makes this convenient?

d = {  
‘Dominic’ =\> ‘Asian’,  
‘John’ =\> ‘Asian’,  
‘Rick’ =\> ‘Spanish’,  
}

# Unfortunately this doesn’t quite do what you want:

i = d.invert  
puts i.inspect

# So:

j = Hash.new { [] }  
d.each { |k,v| j[v] \<\<= k }  
puts j.inspect

---

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 8, 2007, 6:00pm UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/3 "2007-02-08T18:00:44Z")

</div>

On Feb 8, 2007, at 9:12 AM, Dominic S. wrote:

> * * *
> 
> - Rich  
> Here’s one idea:

> > Person = Struct.new(:name, :ethnic)  
> > =\> Person
> 
> > people = [Person.new(“Dominic”, “Asian”), Person.new(“John”,  
> > “Asian”), Person.new("Rick, “Spanish”)]  
> > ^C
> 
> > people = [Person.new(“Dominic”, “Asian”), Person.new(“John”,  
> > “Asian”), Person.new(“Rick”, “Spanish”)]  
> > =\> [#\<struct Person name=“Dominic”, ethnic=“Asian”\>, #\<struct Person  
> > name=“John”, ethnic=“Asian”\>, #\<struct Person name=“Rick”,  
> > ethnic=“Spanish”\>]
> 
> > by\_ethnic = Hash.new  
> > =\> {}
> 
> > people.each do |person|  
> > ?\> (by\_ethnic[person.ethnic] ||= Array.new) \<\< person
> 
> > end  
> > =\> [#\<struct Person name=“Dominic”, ethnic=“Asian”\>, #\<struct Person  
> > name=“John”, ethnic=“Asian”\>, #\<struct Person name=“Rick”,  
> > ethnic=“Spanish”\>]
> 
> > by\_ethnic  
> > =\> {“Asian”=\>[#\<struct Person name=“Dominic”, ethnic=“Asian”\>,  
> > #\<struct Person name=“John”, ethnic=“Asian”\>], “Spanish”=\>[#\<struct  
> > Person name=“Rick”, ethnic=“Spanish”\>]}

Hope that helps.

James Edward G. II

---

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 8, 2007, 9:10pm UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/4 "2007-02-08T21:10:04Z")

</div>

This can help you too…

def ethnic\_group(e, n)

```
 if @eg.nil?
    @eg = {}
 end

 if @eg[e].nil?
    @eg[e] = []
 end

 @eg[e] << n
 return @eg

```

end

@eg = nil

ethnic\_group(‘asian’, ‘domnic’)  
ethnic\_group(‘asian’, ‘john’)  
ethnic\_group(‘spanish’, ‘rich’)

p @eg

---

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 9, 2007, 6:42am UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/5 "2007-02-09T06:42:06Z")

</div>

Looks good. that would’ve been nifty if there was a function to automate  
this…for now looks like we’re rolling our own… i’ll be playing with  
these suggestions. thanks.

SunRaySon wrote:

> This can help you too…
> 
> def ethnic\_group(e, n)
> 
> ```
> if @eg.nil?
> @eg = {}
> end
> 
> if @eg[e].nil?
> @eg[e] = []
> end
> 
> @eg[e] << n
> return @eg
> 
> ```
> 
> end
> 
> @eg = nil
> 
> ethnic\_group(‘asian’, ‘domnic’)  
> ethnic\_group(‘asian’, ‘john’)  
> ethnic\_group(‘spanish’, ‘rich’)
> 
> p @eg

---

<div class="post-metadata">

**Author:** ![eddiewould](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/b5e925/32.png) [@eddiewould](https://www.ruby-forum.com/u/eddiewould)\
**Post date:** [February 9, 2007, 7:46am UTC](https://www.ruby-forum.com/t/grouping-similar-attributes/84908/6 "2007-02-09T07:46:46Z")

</div>

btw, I’m going with Brian’s technique as it’s the least to type : P and  
it works beautifully… thanks again.

Dominic S. wrote:

> Looks good. that would’ve been nifty if there was a function to automate  
> this…for now looks like we’re rolling our own… i’ll be playing with
