Sebastian Zeki
Sebastian Zeki

Reputation: 6874

make sure two fields in array are unique

I need to make sure the follower_id and followed_id are unique in an array which also includes a third number, called value. All are integers. It is the combination of follower_id and followed_id that needs to be unique not the individual numbers themselves. Here is what I have

Relationship.populate 1..20 do |relationship|
        relationship.follower_id = (1..20)
        relationship.followed_id = (1..20)
        relationship.value = rand(1..5)
        end

this would ensure that

1,3,5
1,3,5
2,3,5
1,2,5

would be

1,3,5
2,3,5
1,2,5

Upvotes: 0

Views: 100

Answers (3)

williamcodes
williamcodes

Reputation: 7226

Perfect Uniqueness

Here's a solution assuming the order within the triples matters and you want each triple to be perfectly unique. Just use the uniq method on the Array class. It works like this:

[
  [1,3,5], 
  [1,3,5],
  [2,3,5],
  [1,2,5]
].uniq

#=> [[1, 3, 5], [2, 3, 5], [1, 2, 5]]

Partial Uniqueness

If instead, you only care about the first two being unique, pass the uniq method a block that returns whatever subset you want to be unique. If you only want the first two elements of the triple and can discard duplicates even when the third element is unique, you can just pass it the range 0..1.

[
  [1,3,5], 
  [1,3,5],
  [2,3,5],
  [1,2,5],
  [1,2,6]
].uniq { |triple| triple[0..1] }

#=> [[1, 3, 5], [2, 3, 5], [1, 2, 5]]

Note that the last element, [1,2,6] was discarded even though it ended in 6 because it was considered a duplicate of [1,2,5]. This is because [1,2,5][0..1] #=> [1,2] and [1,2,6][0..1] #=> [1,2].

Upvotes: 1

Cary Swoveland
Cary Swoveland

Reputation: 110675

a = [[1,3,5], [1,3,4], [3,1,2], [2,3,2], [2,3,1], [1,2,3]]

If the order of the first two elements of each element of a is important:

a.uniq { |e| e[0,2] }
  #=> [[1, 3, 5], [3, 1, 2], [2, 3, 2], [1, 2, 3]] 

If the order of the first two elements of each element of a is not important:

require 'set'
a.uniq { |e| Set.new e[0,2] } 
  #=> [[1, 3, 5], [2, 3, 2], [1, 2, 3]] 

Upvotes: 1

Aleksei Matiushkin
Aleksei Matiushkin

Reputation: 121000

Assuming, that the order in pairs is not to be taken into account, and you want to eliminate triples, even having different values, here you go:

a = [[1,3,5], [3,1,5], [2,3,5], [2,3,6], [1,2,5]]
# to count [1,3,5] and [3,1,5] as similar
a.group_by { |(fd,fr,_)| [fd,fr].sort }.values.map &:first
# to count [1,3,5] and [3,1,5] as different
a.group_by { |(fd,fr,_)| [fd,fr] }.values.map &:first
#⇒ [[1,3,5], [3,1,5], [2,3,5], [1,2,5]]

Upvotes: 2

Related Questions