How do I get unique elements in this array?
You can just use the method uniq
. Assuming your array is ary
, call:
ary.uniq{|x| x.user_id}
and this will return a set with unique user_id
s.
How to select unique elements
Helper method
This method uses the helper:
class Array
def difference(other)
h = other.each_with_object(Hash.new(0)) { |e,h| h[e] += 1 }
reject { |e| h[e] > 0 && h[e] -= 1 }
end
end
This method is similar to Array#-. The difference is illustrated in the following example:
a = [3,1,2,3,4,3,2,2,4]
b = [2,3,4,4,3,4]
a - b #=> [1]
c = a.difference b #=> [1, 3, 2, 2]
As you see, a
contains three 3's and b
contains two, so the first two 3's in a
are removed in constructing c
(a
is not mutated). When b
contains as least as many instances of an element as does a
, c
contains no instances of that element. To remove elements beginning at the end of a
:
a.reverse.difference(b).reverse #=> [3, 1, 2, 2]
Array#difference!
could be defined in the obvious way.
I have found many uses for this method: here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here, here and here.
I have proposed that this method be added to the Ruby core.
When used with Array#-
, this method makes it easy to extract the unique elements from an array a
:
a = [1,3,2,4,3,4]
u = a.uniq #=> [1, 2, 3, 4]
u - a.difference(u) #=> [1, 2]
This works because
a.difference(u) #=> [3,4]
contains all the non-unique elements of a
(each possibly more than once).
Problem at Hand
Code
class Array
def uniq_elements(&prc)
prc ||= ->(e) { e }
a = map { |e| prc[e] }
u = a.uniq
uniques = u - a.difference(u)
select { |e| uniques.include?(prc[e]) ? (uniques.delete(e); true) : false }
end
end
Examples
t = [1,2,2,3,4,4,5,6,7,7,8,9,9,9]
t.uniq_elements
#=> [1,3,5,6,8]
t = [1.0, 1.1, 2.0, 3.0, 3.4, 4.0, 4.2, 5.1, 5.7, 6.1, 6.2]
t.uniq_elements { |z| z.round }
# => [2.0, 5.1]
Get unique elements for an array of objects matching two elements only
You want to use the form of Array#uniq that takes a block.
Code
arr.uniq { |instance| [instance.name, instance.value] }
Example
class Something
attr_accessor :id, :name, :value, :comment
def initialize(id, name, value, comment)
@id = id
@name = name
@value = value
@comment = comment
end
end
arr = [Something.new(34175, "abc", 123.3, "something here"),
Something.new(34176, "xyz", 123.3, "something here"),
Something.new(34177, "xyz", 227.3, "something here sdfg"),
Something.new(34178, "xyz", 123.3, "something here sdfg")]
#=> [#<Something:0x000001012cc2f0 @id=34175, @name="abc", @value=123.3,
# @comment="something here">,
# #<Something:0x000001012cc278 @id=34176, @name="xyz", @value=123.3,
# @comment="something here">,
# #<Something:0x000001012cc200 @id=34177, @name="xyz", @value=227.3,
# @comment="something here sdfg">,
# #<Something:0x000001012cc0e8 @id=34178, @name="xyz", @value=123.3,
# @comment="something here sdfg">]
arr.uniq { |instance| [instance.name, instance.value] }
#=> [#<Something:0x000001012cc2f0 @id=34175, @name="abc", @value=123.3,
# @comment="something here">,
# #<Something:0x000001012cc278 @id=34176, @name="xyz", @value=123.3,
# @comment="something here">,
# #<Something:0x000001012cc200 @id=34177, @name="xyz", @value=227.3,
# @comment="something here sdfg">]
How to get the unique elements of an array with a maximum value of attribute
Something like this, maybe?
a = [
{id:1, price:10},
{id:2, price:9},
{id:3, price:8},
{id:1, price:7}
]
b = a.group_by{|h| h[:id]}.
map{|_, v| v.max_by {|el| el[:price]}}
b # => [{:id=>1, :price=>10}, {:id=>2, :price=>9}, {:id=>3, :price=>8}]
How do I find the unique number in an array and return only that number in ruby?
The following doesn't use tallies and will short circuit the search when a unique item is found. First, it returns nil
if the array has fewer than 3 elements, since there's no way to answer the question in that case. If that check is passed, it works by comparing adjacent values. It performs an up-front check that the first two elements are equal—if not, it checks against the third element to see which one is different. Otherwise, it iterates through the array and returns the first value it finds which is unequal. It returns nil
if there is not a distinguished element in the array.
def find_uniq(arr)
return nil if arr.size < 3
if arr[0] == arr[1]
arr.each.with_index do |x, i|
i += 1
return arr[i] if arr[i] != x
end
elsif arr[1] == arr[2]
arr[0]
else
arr[1]
end
end
This also works with non-numeric arrays such as find_uniq(%w(c c c d c c c c))
.
Thanks to Cary Swoveland for reminding me about each_cons
. That can tighten up the solution considerably:
def find_uniq(arr)
return nil if arr.size < 3
if arr[0] != arr[1]
return arr[1] == arr[2] ? arr[0] : arr[1]
end
arr.each_cons(2) { |x, y| return y if y != x }
end
What is the Ruby way to determine if an array has only unique entries?
array.uniq.size == array.size
array.to_set.size == array.size
array.all? { |element| array.count(element) == 1 }
ruby: how to find non-unique elements in array and print each with number of occurrences?
puts a.uniq.
map { | e | [a.count(e), e] }.
select { | c, _ | c > 1 }.
sort.reverse.
map { | c, e | "#{e}:#{c}" }
Related Topics
What's the Difference Between Object and Basicobject in Ruby
How to Enable Cors in Rails 4 App
Implicit Return Values in Ruby
String#Encode Not Fixing "Invalid Byte Sequence in Utf-8" Error
Rspec/Capybara Loading in Progress, Circular Require Considered Harmful
How to Cleanly Initialize Attributes in Ruby with New
Typeerror: Superclass Mismatch for Class Word in Ruby
How to Enable C Extension Support in Jruby
Set Utf-8 as Default for Ruby 1.9.3
How to Say Something Happened "X Minutes Ago" or "X Hours Ago" or "X Days Ago" in Ruby
Error While Installing Nokogiri (1.6.7) on El Capitan
Error Installing Nokogiri on Bundle Install But Already Installed
Ruby Convert Array to Nested Hash
How to Set Up Simple Http Authentication for a Ruby on Rails App on Heroku