Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Rails filtering array of objects by attribute value

So I perform a query to the db and I have a complete array of objects:

@attachments = Job.find(1).attachments 

Now that I have an array of objects I don't want to perform another db query, but I would like to filter the array based on the Attachment object's file_type so that I can have a list of attachments where the file type is 'logo' and then another list of attachments where the file type is 'image'

Something like this:

@logos  = @attachments.where("file_type = ?", 'logo') @images = @attachments.where("file_type = ?", 'image') 

But in memory instead of a db query.

like image 927
joepour Avatar asked Apr 09 '12 06:04

joepour


People also ask

How do you filter an array of objects by value?

One can use filter() function in JavaScript to filter the object array based on attributes. The filter() function will return a new array containing all the array elements that pass the given condition. If no elements pass the condition it returns an empty array.

How do you filter an array of objects in Ruby?

You can use the select method in Ruby to filter an array of objects. For example, you can find all the even numbers in a list. That's quite a bit of code for something so simple!

What does .select do in Ruby?

Array#select() : select() is a Array class method which returns a new array containing all elements of array for which the given block returns a true value. Return: A new array containing all elements of array for which the given block returns a true value.

Does Ruby have a filter method?

The filter() is an inbuilt method in Ruby that returns an array which contains the member value from struct which returns a true value for the given block. Parameters: The function accepts a single parameter block which specifies the condition.


2 Answers

Try :

This is fine :

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' } @images = @attachments.select { |attachment| attachment.file_type == 'image' } 

but for performance wise you don't need to iterate @attachments twice :

@logos , @images = [], [] @attachments.each do |attachment|   @logos << attachment if attachment.file_type == 'logo'   @images << attachment if attachment.file_type == 'image' end 
like image 165
Vik Avatar answered Oct 07 '22 09:10

Vik


If your attachments are

@attachments = Job.find(1).attachments 

This will be array of attachment objects

Use select method to filter based on file_type.

@logos = @attachments.select { |attachment| attachment.file_type == 'logo' } @images = @attachments.select { |attachment| attachment.file_type == 'image' } 

This will not trigger any db query.

like image 23
Soundar Rathinasamy Avatar answered Oct 07 '22 09:10

Soundar Rathinasamy