harshit
harshit

Reputation: 7951

Refactor ruby code to split array into two small arrays

  @open  = Array.new
  @close = Array.new
  @posts.each do |post|
     if !post.status.nil? and post.status == 'Open'
        @open.push(post)
     else
        @close.push(post)
     end
  end

Can i write it in less verbose way ?

Upvotes: 0

Views: 299

Answers (4)

mu is too short
mu is too short

Reputation: 434665

Sounds like a job for partition:

partition { |obj| block } → [ true_array, false_array ]
partition → an_enumerator

Returns two arrays, the first containing the elements of enum for which the block evaluates to true, the second containing the rest.

This should do the job:

@open, @closed = @posts.partition { |p| p.status == 'Open' }

Upvotes: 9

the Tin Man
the Tin Man

Reputation: 160551

Just to help you write code that's more Ruby-like, here's how I'd write your original code:

open_ary  = []
close_ary = []
@posts.each do |post|
  if post.status && post.status == 'Open'
    open_ary << post
  else
    close_ary << post
  end
end

It could be written more concisely, and would remove a couple lines, but it'd lose readability, which is always something to consider. That said, @muistooshort's answer is really the best way to do it because it relies on the partition method which was created for this sort of use-case.

Upvotes: 0

JeanMatheus
JeanMatheus

Reputation: 17

Another idea:

@open = @post.select{ |post| post.status == 'Open'}
@close = @post.reject{ |post| post.status == 'Open'}

Upvotes: 1

Serdar Dogruyol
Serdar Dogruyol

Reputation: 5157

You dont have to check nil explicity. Something like this will do.

@posts.each { |post| post.status == 'Open' ? @open.push post : @close.push }

Upvotes: 0

Related Questions