2

I have an array of hashes:

[{ item_id: 1, relationship_1: 1, relationship_2: 1, value: 'go' },
 { item_id: 2, relationship_1: 2, relationship_2: 2, value: 'stop' },
 { item_id: 3, relationship_1: 2, relationship_2: 1, value: 'stop' }, #remove
 { item_id: 4, relationship_1: 3, relationship_2: 1, value: 'go' },
 { item_id: 5, relationship_1: 1, relationship_2: 2, value: 'go' }] #remove

I want the lines commented to be removed. The need is to remove all lines that have relationship_1 and value in common. The only way I can think of is:

items.each do |i|
  items.each do |k|
    if i.item_id != k.item_id and i.relationship_1 == k.relationship_1 and i.value == k.value
      items.remove(k)
    end
  end
end

This is not working as intended. What is the most "Ruby" way to remove those offending items?

2
  • How do you define "similar"? Also please read about the difference between &&/|| & and/or in Ruby. They are not the same. Commented Mar 13, 2012 at 17:52
  • In this case I mean by having a specific set of values that are equal, there wasn't really a better way to word it in the title. Commented Mar 13, 2012 at 18:03

3 Answers 3

3

Unfortunately, uniq_by isn't available in Ruby core. Pull it in with require 'activesupport'.

items.uniq_by {|h| [h[:replationship_1], h[:value]] }

Edit: As noted by @mu below, Ruby 1.9's uniq also works:

items.uniq{|h| [h[:replationship_1], h[:value]] }
Sign up to request clarification or add additional context in comments.

6 Comments

Fortunately I am using Rails 3. I didn't want extra requirements if it didn't need them. Seeing as these objects are ActiveResource objects, this will work great. Thank you.
The implementation of uniq_by is (i think) actually rather clever and worthy of inspection.
Nonsense, sort of. 1.9's Array#uniq can take a block and Array#uniq certainly is in the core.
@muistooshort I thought it did, but I was surprised when I looked at the docs and the method's signature doesn't state it takes a block so I didn't even bother to look at the examples. (Thankfully this doc issue is fixed in Ruby trunk.)
@muistooshort Good call. Didn't know that.
|
3

group_by{ |item| [item.relationship_1, item.value] }.values.map(&:first)?

UPDATE

Oops, it was a hash:

group_by{ |item| [item[:relationship_1], item[:value]] }.values.map(&:first)

or

group_by{ |item| item.values_at(:relationship_1, :value) }.values.map(&:first)

1 Comment

why item.relationship_1 dosen't work on my ruby 1.9.2 install? I must make item[:relationship_1] to work.
1

Maybe this function will help. I found it mentioned in this thread, and if I am not wrong it is part of latest ruby on rails.

a.uniq_by {|t| [t.replationship_1, t.value]}

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.