[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

Re: Returning a duplicate from an Array

Andy Cooper

1/13/2009 10:19:00 PM

> > Hey guys,
> > I have an array of names that may contain duplicates. What I=20
> > would like
> > to do is return an array OF THE DUPLICATES. I was looking around at
> > various built-in methods for arrays, but the closest thing I=20
> > can find is
> > Array.uniq, which returns the array without the duplicates.
> >=20
> > Any suggestions on how to do this?
> >=20
> > Thanks,
> > - Jeff Miller
> > --=20
>=20
> Without really looking into it a quick and dirty way would be to just
> subtract the results of .uniq from the initial array.
>=20
> Andy Cooper.

Nevermind that wont work afterall, wasn't thinking about how arrays work
at the time.

def dups(ary=3D[])
uniq=3Dary.uniq
ary.reject{|z| if(uniq.include?(z));q-=3D[z];true;end}
end

There that should do the trick. Still very probably not the best of
ways to do it though.

Andy Cooper.

6 Answers

Brian Candler

1/14/2009 9:47:00 AM

0

This version does only a single pass through the array:

def dups(ary)
seen = {}
ary.find_all { |x| seen[x] || (seen[x]=true; false) }
end

p dups([1,2,3,1,4,5,6,3])
--
Posted via http://www.ruby-....

Pierre Pat

1/15/2009 2:35:00 AM

0

I'd do like this:
a.select{|x| a.index(x) != a.rindex(x)}.uniq

Now, I wouldn't know which one is more efficient, but coding wise, I
like that way :-)

--
Posted via http://www.ruby-....

Jimmy Kofler

1/15/2009 11:19:00 AM

0

> Pierre Pat wrote:
> I'd do like this:
> a.select{|x| a.index(x) != a.rindex(x)}.uniq
>
> Now, I wouldn't know which one is more efficient, but coding wise, I
> like that way :-)

Here's yet another take on it:

class Array
def dups
uniq.select{ |e| (self-[e]).size < self.size - 1 }
end
end

p [ 1, 1, 2, 2, 3, 3, 4, 5 ].dups #=> [1, 2, 3]

see: http://snippets.dzone.com/posts...

Cheers,

j.k.
--
Posted via http://www.ruby-....

Tiago Nogueira

1/15/2009 11:42:00 AM

0

Jimmy Kofler escreveu:
>> Pierre Pat wrote:
>> I'd do like this:
>> a.select{|x| a.index(x) != a.rindex(x)}.uniq
>>
>> Now, I wouldn't know which one is more efficient, but coding wise, I
>> like that way :-)
>>
>
> Here's yet another take on it:
>
> class Array
> def dups
> uniq.select{ |e| (self-[e]).size < self.size - 1 }
> end
> end
>
> p [ 1, 1, 2, 2, 3, 3, 4, 5 ].dups #=> [1, 2, 3]
>
> see: http://snippets.dzone.com/posts...
>
> Cheers,
>
> j.k.
>
I Think that the way :

class Array
def dups
uniq.select{ |e| (self-[e]).size < self.size - 1 }
end
end
p [ 1, 1, 2, 2, 3, 3, 4, 5 ].dups #=> [1, 2, 3]


is more elegant!

tiago

Klaus Stein

1/15/2009 12:08:00 PM

0

Pierre Pat <theyojimbo@gmail.com> wrote:
> I'd do like this:
> a.select{|x| a.index(x) != a.rindex(x)}.uniq
>
> Now, I wouldn't know which one is more efficient, but coding wise, I
> like that way :-)
>
If order is not important:
h = Hash.new(0)
a.each { |x| h[x]+=1 }
h.select {|k,v| v>1 }.keys

should be O(n) and with only one iteration through a.

Klaus
--
http://lapiz...

The Answer is 42. And I am the Answer. Now I am looking for the Question.

Jesús Gabriel y Galán

1/15/2009 12:22:00 PM

0

On Thu, Jan 15, 2009 at 12:18 PM, Jimmy Kofler <koflerjim@mailinator.com> wrote:
>
> class Array
> def dups
> uniq.select{ |e| (self-[e]).size < self.size - 1 }
> end
> end
>
> p [ 1, 1, 2, 2, 3, 3, 4, 5 ].dups #=> [1, 2, 3]

Regarding this and other solutions: the OP accepted a solution from
Andy Cooper which return *all* duplicates.
I mean, if a number appears three times, it will appear two in the
solution, and not one:

irb(main):001:0> a = [1,1,1,1,2,2,3,4,5,5,5]
=> [1, 1, 1, 1, 2, 2, 3, 4, 5, 5, 5]
irb(main):008:0> class Array
irb(main):009:1> def dups
irb(main):010:2> uniq.select{ |e| (self-[e]).size < self.size - 1 }
irb(main):011:2> end
irb(main):012:1> end
=> nil
irb(main):013:0> a.dups
=> [1, 2, 5]

Should be [1,1,1,2,3,4,5,5]. If order is not important:

irb(main):014:0> class Array
irb(main):015:1> def dups
irb(main):016:2> h = Hash.new 0
irb(main):017:2> each {|x| h[x] += 1}
irb(main):018:2> h.inject([]) {|res, (k,v)| res << ([k] * (v-1)) if v
> 1; res.flatten}
irb(main):019:2> end
irb(main):020:1> end
=> nil
irb(main):021:0> a.dups
=> [5, 5, 1, 1, 1, 2]

Jesus.