2

Let's suppose that we class SomeClass.

class SomeClass < SomeClassThatAssignAttributesOnInitialization
  attr_accessor :group
  attr_accessor :name
end

And array of it instances

arr = [SomeClass.new(group:0, name:'one'),
       SomeClass.new(group:0, name:'two'),
       SomeClass.new(group:1, name:'three'),
       SomeClass.new(group:1, name:'four')]

I need to put first element of each group into array.

Now it works next way

current_group = nil
first_elements = arr.map do |instance|
  if current_group != instance.group
    current_group = instance.group
    instance.name
  end
end

This works fine but i think that there is some kind of "Ruby" way to do it.

Can anybody help me?

Thanks

1

4 Answers 4

3

Ruby has a handy group_by method on Enumerable object, which returns a Hash:

arr.group_by(&:group)
# => {0=>[#<SomeClass group=0, name="one">, #<SomeClass group=0, name="two">], 1=>[#<SomeClass group=1, name="three">, #<SomeClass group=1, name="four">]}

So just chain a few methods on to the end of that:

arr.group_by(&:group).values.map {|vs| vs[0].name}
# => ["one", "three"]
Sign up to request clarification or add additional context in comments.

Comments

2
arr.group_by(&:group).values.map(&:first)

Comments

1

why not just:

first_elements = arr.map(&:name)

2 Comments

I need to take name from first element of each group. You example will take names from all elements
yeah sorry for that - I have noticed this after writing my answer.
1
SomeClass = Struct.new(:group, :name)

arr = [
  SomeClass.new(0, 'one'),
  SomeClass.new(0, 'two'),
  SomeClass.new(1, 'three'),
  SomeClass.new(1, 'four')
]

arr.group_by(&:group).values.map(&:first)
# => [
#   #<struct SomeClass group=0, name="one">,
#   #<struct SomeClass group=1, name="three">
# ]

Or to get just the names:

arr.group_by(&:group).values.map(&:first).map(&:name)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.