[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Detecting duplicates in an array, anything in the standard library ?

Thibaut Barrère

8/19/2007 10:38:00 AM

Hi!

Just wondering if there is something simple already built in the std
library to remove duplicates from an array (or an enumerable). I've
seen and used various approaches, like:

module Enumerable
def dups
inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
end
end

which will give:

> %w(a b c c).dups
=> ["c"]

Anything more elegant ?

cheers

Thibaut

34 Answers

Wolfgang Nádasi-donner

8/19/2007 11:20:00 AM

0

Thibaut Barrère wrote:
> Anything more elegant ?

No! :-)) - I tried it only using Arrays...

a = [1,2,3,4,5,4,2,2]
p a.inject([[],a[1..-1]]){|r,e|r[1].include?(e) ? [r[0]<<e, r[1][1..-1]]
: [r[0], r[1][1..-1]]}[0].uniq # => [2, 4]
b = %w(a b c c)
p b.inject([[],b[1..-1]]){|r,e|r[1].include?(e) ? [r[0]<<e, r[1][1..-1]]
: [r[0], r[1][1..-1]]}[0].uniq # => ["c"]

Wolfgang Nádasi-Donner
--
Posted via http://www.ruby-....

David A. Black

8/19/2007 11:34:00 AM

0

Wolfgang Nádasi-donner

8/19/2007 12:07:00 PM

0

David A. Black wrote:
> Hi --
>
> On Sun, 19 Aug 2007, Wolfgang Nádasi-Donner wrote:
>
>> : [r[0], r[1][1..-1]]}[0].uniq # => ["c"]
> How about:
>
> >> a = [1,2,3,4,5,4,2,2]
> => [1, 2, 3, 4, 5, 4, 2, 2]
> >> a.inject([]) {|acc,e| acc << e unless acc.include?(e); acc }
> => [1, 2, 3, 4, 5]
>
>
> David

The problem is, that he wants all non unique elements. Unfortunately the
difference of two arrays doesn't care about double elements,
otherwise...

irb(main):004:0> a
=> [1, 2, 3, 4, 5, 4, 2, 2]
irb(main):005:0> b
=> [1, 2, 3, 4, 5]
irb(main):006:0> a-b
=> []

...would work. My solution is not recommended at all - it's sunday after
lunch time, and I had the decision between cleaning the dishes or to do
some nice things before...

Wolfgang Nádasi-Donner
--
Posted via http://www.ruby-....

David A. Black

8/19/2007 12:34:00 PM

0

Ari Brown

8/19/2007 1:01:00 PM

0


On Aug 19, 2007, at 6:39 AM, Thibaut Barrère wrote:

> Hi!
>
> Just wondering if there is something simple already built in the std
> library to remove duplicates from an array (or an enumerable). I've
> seen and used various approaches, like:
>
> module Enumerable
> def dups
> inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
> end
> end
>
> which will give:
>
>> %w(a b c c).dups
> => ["c"]
>
> Anything more elegant ?

Couldn't you also just do a union with itself?

a = %w(a b c b a)
b = a & a #=> ["a", "b", "c"]

Score one for me :-))
~ Ari
English is like a pseudo-random number generator - there are a
bajillion rules to it, but nobody cares.


David A. Black

8/19/2007 1:07:00 PM

0

Ari Brown

8/19/2007 1:24:00 PM

0


On Aug 19, 2007, at 9:06 AM, David A. Black wrote:

> I think that just reinvents uniq (see my previous reinvention :-)

The only reason I'll accept that

is because you wrote the book I'm reading.

---------------------------------------------------------------|
~Ari
"I don't suffer from insanity. I enjoy every minute of it" --1337est
man alive




William James

8/19/2007 7:33:00 PM

0

On Aug 19, 5:38 am, Thibaut Barr?re <thibaut.barr...@gmail.com> wrote:
> Hi!
>
> Just wondering if there is something simple already built in the std
> library to remove duplicates from an array (or an enumerable). I've
> seen and used various approaches, like:
>
> module Enumerable
> def dups
> inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
> end
> end
>
> which will give:
>
> > %w(a b c c).dups
>
> => ["c"]
>
> Anything more elegant ?
>
> cheers
>
> Thibaut

Here's a modification of a technique used by
Simon Kroger:

class Array
def dups
values_at( * (0...size).to_a - uniq.map{|x| index(x)} )
end
end
==>nil

%w(a b a c c d).dups
==>["a", "c"]

Thibaut Barrère

8/19/2007 7:58:00 PM

0

Thanks for all your replies!

Trans

8/19/2007 8:06:00 PM

0



On Aug 19, 12:34 pm, William James <w_a_x_...@yahoo.com> wrote:
> On Aug 19, 5:38 am, Thibaut Barrère <thibaut.barr...@gmail.com> wrote:
>
>
>
> > Hi!
>
> > Just wondering if there is something simple already built in the std
> > library to remove duplicates from an array (or an enumerable). I've
> > seen and used various approaches, like:
>
> > module Enumerable
> > def dups
> > inject({}) {|h,v| h[v]=h[v].to_i+1; h}.reject{|k,v| v==1}.keys
> > end
> > end
>
> > which will give:
>
> > > %w(a b c c).dups
>
> > => ["c"]
>
> > Anything more elegant ?
>
> > cheers
>
> > Thibaut
>
> Here's a modification of a technique used by
> Simon Kroger:
>
> class Array
> def dups
> values_at( * (0...size).to_a - uniq.map{|x| index(x)} )
> end
> end
> ==>nil


Does everyone agree that #dups is the best name for this? I recently
added this to Facets as #duplicates to avoid proximity to #dup. Is
that reasonable?

(Facets already had #nonuniq, btw.)

T.