How to remove duplicates in a hash in Ruby on Rails?
I know this is an old thread, but Rails has a method on 'Enumerable' called 'index_by' which can be handy in this case:
list = [
{
:lname => "Brown",
:email => "james@intuit.com",
:fname => "James"
},
{
:lname => nil,
:email => "brad@intuit.com",
:fname => nil
},
{
:lname => "Smith",
:email => "brad@intuit.com",
:fname => "Brad"
},
{
:lname => nil,
:email => "brad@intuit.com",
:fname => nil
},
{
:lname => "Smith",
:email => "brad@intuit.com",
:fname => "Brad"
},
{
:lname => nil,
:email => "brad@intuit.com",
:fname => nil
}
]
Now you can get the unique rows as follows:
list.index_by {|r| r[:email]}.values
To merge the rows with the same email id.
list.group_by{|r| r[:email]}.map do |k, v|
v.inject({}) { |r, h| r.merge(h){ |key, o, n| o || n } }
end
Custom but efficient method:
list.inject({}) do |r, h|
(r[h[:email]] ||= {}).merge!(h){ |key, old, new| old || new }
r
end.values
How to remove duplicate entries from a hash based on a value
hash_list.to_a
.uniq! { |_, v| v['unit_id'] }
.to_h
But note that, the duplicates are removed only based on the key unit_id
.
To do it based on multiple keys,
hash_list.to_a
.uniq! { |_, v| v.values_at('unit_id','_destroy') }
.to_h
Please have a look at Hash#values_at
Output
>> hash_list = { "a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"}, "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"}, "c"=>{"unit_id"=>"43", "dep_id"=>"154", "_destroy"=>"false"}, "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"} }
#=> {"a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"}, "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"}, "c"=>{"unit_id"=>"43", "dep_id"=>"154", "_destroy"=>"false"}, "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"}}
>> hash_list.to_a.uniq! { |_, v| v.values_at('unit_id','_destroy') }.to_h
#=> {"a"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"false"}, "b"=>{"unit_id"=>"43", "dep_id"=>"153", "_destroy"=>"1"}, "d"=>{"unit_id"=>"42", "dep_id"=>"154", "_destroy"=>"false"}}
How to remove duplicate row in array of hashes on Ruby on rails
Here is another group by option
array_of_hashes.group_by {|h| h.values_at("ID","Date")}.transform_values do |v|
v.find {|r| r["Rate"]}
end
#=> {[100, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>100, "Rate"=>10, "Count"=>1},
# [101, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>101, "Rate"=>25, "Count"=>3},
# [102, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>102, "Rate"=>35, "Count"=>0},
# [103, "2019-05-6"]=>{"Date"=>"2019-05-6", "ID"=>103, "Rate"=>20, "Count"=>6}}
group by id and date then transform the Hash
values to the first Hash
where "Rate" is not nil
.
If multiple values are acceptable then find_all
or select
could be substituted for find
.
If you want the original structure maintained just add values
to the end.
How to add hashes to itself and remove duplicates in Ruby?
for Ruby >= 2.4.0 - method #transform_values
with methods #inject
and #merge
h.transform_values { |v| v.inject(:merge) }
For lower versions:
h.map { |k, v| [k, v.inject(:merge)] }.to_h
Ruby: array of hashes - how to remove duplicates based on the hash key which is an array
So long as your kappa
function produces the same value for u,p
as for p,u
then you can do this:
@result = @user_array.each_with_object({ }) do |u, h|
@user_array.each do |p|
next if (u == p)
h[[u, p].sort] ||= kappa(u, p, "ipf")
end
end
That populates the values once and once only. If you want to do it where the last value sticks then change ||=
to =
.
Ruby remove duplicate entries in array of hashes but based on more than one value
uniq
accepts a block. If a block is given, it will use the return value of the block for comparison.
Your code was close to the solution, but in your code the return value was only a_track[:composer]
which is the last evaluated statement.
You can join the attributes you want into a string and return that string.
new_tracks.uniq { |track| [track[:name], track[:artist], track[:composer]].join(":") }
A possible refactoring is
new_tracks.uniq { |track| track.attributes.slice('name', 'artist', 'composer').values.join(":") }
Or add a custom method in your model that performs the join, and call it
class Track < ActiveRecord::Base
def digest
attributes.slice('name', 'artist', 'composer').values.join(":")
end
end
new_tracks.uniq(&:digest)
get rid of duplicates in nested hash
I'm assuming that in the case of { :GE => nil, "GE" => "successful" }
, you want to use the first truthy value ("successful") and make sure the key is a symbol:
result = given.transform_values do |inner_hsh|
inner_hsh.group_by do |k,v|
k.to_sym
end.transform_values do |key_vals|
key_vals.to_h.values.find(&:itself)
end
end
How to remove duplicate entry from ruby hash
Just call uniq!
method to change hotels array in-place, uniq!
takes a block where you can return what you are comparing
hotels.uniq!{|hotel| hotel.id}
e.g. see usage
irb(main):001:0> class Hotel
irb(main):002:1> attr_reader :id
irb(main):002:1> def initialize(id, name)
irb(main):003:2> @id = id
irb(main):004:2> @name = name
irb(main):005:2> end
irb(main):006:1> end
=> nil
irb(main):008:0> hotels = [Hotel.new(1,'one'), Hotel.new(1,'one'), Hotel.new(2,'two'), Hotel.new(2,'two')]
=> [#<Hotel:0x007fa6b9148c48 @id=1, @name="one">, #<Hotel:0x007fa6b9148b58 @id=1, @name="one">, #<Hotel:0x007fa6b9148a40 @id=2, @name="two">, #<Hotel:0x007fa6b9148950 @id=2, @name="two">]
irb(main):013:0> hotels.uniq!{|hotel| hotel.id}
=> [#<Hotel:0x007fa6b9148c48 @id=1, @name="one">, #<Hotel:0x007fa6b9148a40 @id=2, @name="two">]
Delete duplicates from a hash?
Suppose you can retrieve ARL_DISPLAY_NR
field from an instance art
of ArtLookup
like this:
art[:ARL_DISPLAY_NR]
Then you can delete duplicates according to ARL_DISPLAY_NR
field by:
hash_array = [ artLookup_foo, artLookup_bar, ... ]
# this will keep the last one in a group of duplicates
Hash[ hash_array.map{|h| [h[:ARL_DISPLAY_NR], h]} ].values
# or keep the first one
Hash[ hash_array.reverse.map{|h| [h[:ARL_DISPLAY_NR], h]} ].values
However, it doesn't guarantee to keep the original order in the previous array.
Related Topics
Ruby Indented Multiline Strings
Ruby Converting String Encoding from Iso-8859-1 to Utf-8 Not Working
Activerecord Connection Warning. (Database Connections Will Not Be Closed Automatically)
Using Bsearch to Find Index for Inserting New Element into Sorted Array
Rails Custom Validation Based on a Regex
How to Remove Non-Printable/Invisible Characters in Ruby
Ruby on Rails Multiple Http Request at the Same Time
Testing Routes with Subdomain Constraints Using Rspec
How to Click on a Specific Coordinates of an Element
Cannot Install Any Version of Ruby on Mojave - Internal Ranlib Command Failed
How to Get a Selenium/Ruby Bot to Wait Before Performing an Action
How to Convert a Ruby String with Brackets to an Array
How to Inspect What Is the Default Value for Optional Parameter in Ruby's Method
What Is the Purpose of 'Kernel'