# Modifying Select Elements in Array of Objects

**URL:** <https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471>\
**Category:** Ruby\
**Created:** [March 20, 2010, 10:07pm UTC](https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471 "2010-03-20T22:07:44Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![glenn\_nz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/3e96dc/32.png) [@glenn\_nz](https://www.ruby-forum.com/u/glenn_nz)\
**Post date:** [March 20, 2010, 10:07pm UTC](https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471/1 "2010-03-20T22:07:44Z")

</div>

Hi,

I have an array of objects, and the objects have some attributes. I’d  
like to be able to modify selected elements in the array based on any of  
those attributes.

For example, suppose I have a have an array of Albums, like this:

class Album  
attr\_reader :name, :band, :like  
attr\_writer :like

def initialize(name, band)  
@name = name  
@band = band  
@like = nil  
end  
end

albums = []  
albums \<\< Album.new(“Exile on Main Street”, “The Rolling Stones”)  
albums \<\< Album.new(“St. Peppers”, “The Beatles”)  
albums \<\< Album.new(“The White Album”, “The Beatles”)

I want to be able to selectively modify the elements of the albums array  
based on, for example, the band. In other words, I want to be able to  
able to change the like instance variable in each object to true with a  
method.

Here’s what I have so far:

puts albums.collect { |a| a.like = true if a.band == “The Beatles”;  
a}.inspect

Using collect like this works, but it seems awkward to me to have to  
iterate through the whole array just to find the element (or elements)  
that I want to change. I’d like to be able just to select the elements  
I want, make the changes, and leave the rest of the elements unchanged.  
Is there a better way to do this?

---

<div class="post-metadata">

**Author:** ![glenn\_nz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/3e96dc/32.png) [@glenn\_nz](https://www.ruby-forum.com/u/glenn_nz)\
**Post date:** [March 20, 2010, 10:21pm UTC](https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471/2 "2010-03-20T22:21:51Z")

</div>

On Mar 20, 3:07 pm, Glenn R. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> I have an array of objects, and the objects have some attributes. I’d  
> like to be able to modify selected elements in the array based on any of  
> those attributes.

See Array#select and Array#find.

e.g.  
albums.select{ |a| a.band==“The Beatles” }.each{ |a| a.like=true }

> Using collect like this works, but it seems awkward to me to have to  
> iterate through the whole array just to find the element (or elements)  
> that I want to change.

Without some previously-established alternative lookup mechanism, such  
as a Hash, any implementation is going to have to walk through the  
entire array to find multiple matching items. Array#find will stop as  
soon as it finds one item, though.

For example (assuming you still need your albums array):

# Do this once

albums\_by\_band = albums.group\_by{ |a| a.band }

# Do this for each time you need to look up an array of albums by a

band  
albums\_by\_band[“The Beatles”].each{ |a| a.like = true }

---

<div class="post-metadata">

**Author:** ![glenn\_nz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/3e96dc/32.png) [@glenn\_nz](https://www.ruby-forum.com/u/glenn_nz)\
**Post date:** [March 20, 2010, 10:25pm UTC](https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471/3 "2010-03-20T22:25:57Z")

</div>

On 03/20/2010 10:07 PM, Glenn R. wrote:

> attr\_writer :like  
> albums \<\< Album.new(“St. Peppers”, “The Beatles”)  
> a}.inspect
> 
> Using collect like this works, but it seems awkward to me to have to  
> iterate through the whole array just to find the element (or elements)  
> that I want to change. I’d like to be able just to select the elements  
> I want, make the changes, and leave the rest of the elements unchanged.  
> Is there a better way to do this?

There is a different way but it’s not really better because now you  
iterate the elements that you want to change twice:

albums.select {|a| a.band == “The Beatles”}.each {|a| a.like = true}

If your Albums are stored in this single Array only you have no other  
choice than to iterate all. If you want mo re efficient operation then  
you need to create a more complex data structure which non only manages  
the list of Albums but also one or more indexes (typically Hashes)  
depending on your typical queries.

Kind regards

robert

---

<div class="post-metadata">

**Author:** ![glenn\_nz](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/3e96dc/32.png) [@glenn\_nz](https://www.ruby-forum.com/u/glenn_nz)\
**Post date:** [March 21, 2010, 12:03am UTC](https://www.ruby-forum.com/t/modifying-select-elements-in-array-of-objects/185471/4 "2010-03-21T00:03:52Z")

</div>

Robert K. wrote:

> If your Albums are stored in this single Array only you have no other  
> choice than to iterate all. If you want mo re efficient operation then  
> you need to create a more complex data structure which non only manages  
> the list of Albums but also one or more indexes (typically Hashes)  
> depending on your typical queries.
> 
> Kind regards
> 
> robert

Thanks, guys. This helped.
