Uniq by Object Attribute in Ruby

Uniq by object attribute in Ruby

Use Array#uniq with a block:

@photos = @photos.uniq { |p| p.album_id }

How do I get unique attribute values of an array of objects?

It's not clear on your post, but if that "array" is instead an ActiveRecord::Relation, you could do .distinct.pluck(:attr_name), for example: User.distinct.pluck(:role) => SELECT DISTINCT "users"."role" FROM "users"

If it's actually an array (my_objects.is_a? Array), the solution is my_objects.map(&:attr_name).uniq.

Select unique objects based on an attribute

uniq could take a block

my_array.uniq { |obj| [obj.origin.name, obj.destination.name]}
.map { |obj| [obj.origin, obj.destination] }

# or

my_array.map { |obj| [obj.origin, obj.destination] }
.uniq { |pair| pair.map(&:name) }

Parameterized Array#uniq (i.e., uniq_by)

Activesupport has a Array#uniq_by, and this is the code:

class Array
def uniq_by
hash, array = {}, []
each { |i| hash[yield(i)] ||= (array << i) }
array
end
end

Facets also has a Enumerable#uniq_by:

module Enumerable    
def uniq_by
h = {}
inject([]) {|a,x| h[yield(x)] ||= a << x}
end
end

If active record object has attribute and is unique

You can use after_commit:

after_commit :do_foo, on: :create

private

def do_foo
return if Model.exists?(token: token)

do_what_you_have_to_do
end

The method checks if there's already a record with the same token, if so it returns from the method itself. Otherwise you can proceed to do what you need.

Remove duplicates from array of objects based on multiple attributes in ruby

You can try:

uniq_fonts = fonts.uniq { |f| [ f.name, f.color ] }

You can defined your own values_at method like:

class Font
attr_accessor :color, :name, :type

def values_at *args
args.map { |method_name| self.public_send method_name }
end
end

And then do like :

fonts.uniq { |f| f.values_at(:name, :color)}

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">]

Get array of unique ActiveRecord objects

The deprecated .uniq_by method will work i suppose. The documentation suggest to use Array.uniq instead, but its not the same.
(Array.uniq is ignoring the given block)

If you don't want to use .uniq_by, try this:
post.messages.group(:user_id)



Related Topics



Leave a reply



Submit