[lnkForumImage]
TotalShareware - Download Free Software

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


 

Forums >

comp.lang.ruby

sort_by { rand } not working

Mike Dershowitz

8/26/2007 1:25:00 PM

Hello:

I've got an array of arrays that I'd like to sort_by random. each
individual array is just a hash of a value and then an object. Is there
some reason why sort_by { rand } wouldn't work? My code is simple (teams
is populated with a db call):

@teams.each do |t|
@all << ["t",t]
end
#current not working
@all.sort_by { rand }

Any ideas? Am I stretching the limit of the rand function?

Thanks!

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

33 Answers

Phrogz

8/26/2007 2:17:00 PM

0

On Aug 26, 7:25 am, Mike Dershowitz <michael.dershow...@jpmchase.com>
wrote:
> @teams.each do |t|
> @all << ["t",t]
> end
> #current not working
> @all.sort_by { rand }

#sort_by doesn't modify the original array, it returns a new one.

Try @all = @all.sort_by{ rand }


Ken Bloom

8/26/2007 2:23:00 PM

0

On Sun, 26 Aug 2007 22:25:08 +0900, Mike Dershowitz wrote:

> Hello:
>
> I've got an array of arrays that I'd like to sort_by random. each
> individual array is just a hash of a value and then an object. Is there
> some reason why sort_by { rand } wouldn't work? My code is simple (teams
> is populated with a db call):
>
> @teams.each do |t|
> @all << ["t",t]
> end
> #current not working
> @all.sort_by { rand }

sort_by returns the sorted list
sort_by! sorts the list in place

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

Ken Bloom

8/26/2007 3:11:00 PM

0

On Sun, 26 Aug 2007 09:22:38 -0500, Ken Bloom wrote:

> On Sun, 26 Aug 2007 22:25:08 +0900, Mike Dershowitz wrote:
>
>> Hello:
>>
>> I've got an array of arrays that I'd like to sort_by random. each
>> individual array is just a hash of a value and then an object. Is
>> there some reason why sort_by { rand } wouldn't work? My code is simple
>> (teams is populated with a db call):
>>
>> @teams.each do |t|
>> @all << ["t",t]
>> end
>> #current not working
>> @all.sort_by { rand }
>
> sort_by returns the sorted list
> sort_by! sorts the list in place

Whoops. As soon as I posted, I noticed that there is no sort_by!.

--Ken

--
Ken Bloom. PhD candidate. Linguistic Cognition Laboratory.
Department of Computer Science. Illinois Institute of Technology.
http://www.iit.edu...

botp

8/26/2007 5:32:00 PM

0

On 8/26/07, Ken Bloom <kbloom@gmail.com> wrote:
> Whoops. As soon as I posted, I noticed that there is no sort_by!.

try

sort!{rand}


kind regards -botp

James Gray

8/26/2007 6:07:00 PM

0

On Aug 26, 2007, at 12:31 PM, botp wrote:

> On 8/26/07, Ken Bloom <kbloom@gmail.com> wrote:
>> Whoops. As soon as I posted, I noticed that there is no sort_by!.
>
> try
>
> sort!{rand}

That's not a random sort. In fact, it's equivalent to sort! { 1 }:

>> data = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> data.sort! { rand }
=> [9, 5, 0, 6, 2, 7, 4, 8, 3, 1]
>> data.sort! { rand }
=> [1, 7, 9, 4, 0, 8, 2, 3, 6, 5]
>> data.sort! { rand }
=> [5, 8, 1, 2, 9, 3, 0, 6, 4, 7]
>> data = (0..9).to_a
=> [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>> data.sort! { 1 }
=> [9, 5, 0, 6, 2, 7, 4, 8, 3, 1]
>> data.sort! { 1 }
=> [1, 7, 9, 4, 0, 8, 2, 3, 6, 5]
>> data.sort! { 1 }
=> [5, 8, 1, 2, 9, 3, 0, 6, 4, 7]

It would be better to use:

data = data.sort_by { … }

James Edward Gray II

Stefan Rusterholz

8/26/2007 6:12:00 PM

0

botp wrote:
> On 8/26/07, Ken Bloom <kbloom@gmail.com> wrote:
>> Whoops. As soon as I posted, I noticed that there is no sort_by!.
>
> try
>
> sort!{rand}
>
>
> kind regards -botp

That's equivalent to sort! { 1 } and rather predictable (sort/sort!
expects -1, 0 or 1 as value, rand is 0..1) and hence IMHO pointless.

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

Stefan Rusterholz

8/26/2007 6:23:00 PM

0

James Gray wrote:
> On Aug 26, 2007, at 12:31 PM, botp wrote:
>
>> On 8/26/07, Ken Bloom <kbloom@gmail.com> wrote:
>>> Whoops. As soon as I posted, I noticed that there is no sort_by!.
>>
>> try
>>
>> sort!{rand}
>
> That's not a random sort. In fact, it's equivalent to sort! { 1 }:
>
> >> data = (0..9).to_a
> => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >> data.sort! { rand }
> => [9, 5, 0, 6, 2, 7, 4, 8, 3, 1]
> >> data.sort! { rand }
> => [1, 7, 9, 4, 0, 8, 2, 3, 6, 5]
> >> data.sort! { rand }
> => [5, 8, 1, 2, 9, 3, 0, 6, 4, 7]
> >> data = (0..9).to_a
> => [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
> >> data.sort! { 1 }
> => [9, 5, 0, 6, 2, 7, 4, 8, 3, 1]
> >> data.sort! { 1 }
> => [1, 7, 9, 4, 0, 8, 2, 3, 6, 5]
> >> data.sort! { 1 }
> => [5, 8, 1, 2, 9, 3, 0, 6, 4, 7]
>
> It would be better to use:
>
> data = data.sort_by { � }
>
> James Edward Gray II

Well, it has the (extremely little) chance of being 0, which introduces
a very very small randomness :)

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

Lionel Bouton

8/26/2007 6:31:00 PM

0

James Edward Gray II wrote:
>
> It would be better to use:
>
> data = data.sort_by { â?¦ }

I was wondering about a crazy idea of mine: "sort!{rand<=>rand}" and
from my bench results it's a waste of time (it's even dangerous, see
below). I suspect sort_by begins by mapping the block results and then
sorts based on the map (it's roughly 4x faster than sort!{ rand <=> rand }).
sort!{rand<=>rand} obviously can't do that and must call the block each
time a comparison must be done (I suspect that more rand calls make it
slower even if it can avoid copying things and instead do in-place
modifications ... or that the Ruby sort algorithm doesn't like
comparison results changing...).

Obviously depending on the sort algorithm used it might not even
converge on a result (the dangerous part...).

Lionel

Dan Zwell

8/26/2007 9:31:00 PM

0

Mike Dershowitz wrote:
> Hello:
>
> I've got an array of arrays that I'd like to sort_by random. each
> individual array is just a hash of a value and then an object. Is there
> some reason why sort_by { rand } wouldn't work? My code is simple (teams
> is populated with a db call):
>
> @teams.each do |t|
> @all << ["t",t]
> end
> #current not working
> @all.sort_by { rand }
>
> Any ideas? Am I stretching the limit of the rand function?
>
> Thanks!
>
> Mike

Mike,

This has been discussed here before. Your two best choices are:
@all = @all.sort_by {rand}
or

for i in 0...@all.length
j = i+rand(@all.length-i)
@all[i], @all[j] = @all[j], @all[i]
end

The second one will be faster, but you probably shouldn't care on small
arrays.

Dan

Lionel Bouton

8/26/2007 9:59:00 PM

0

Dan Zwell wrote:
>
> for i in 0...@all.length
> j = i+rand(@all.length-i)
> @all[i], @all[j] = @all[j], @all[i]
> end
>
> The second one will be faster, but you probably shouldn't care on
> small arrays.
>

You could even optimize this further with 0...@all.length-1 instead of
0...@all.length (the last loop is a noop), but I agree, this is too much
pain for the eyes to bother unless it becomes a real performance problem.

Sorry if this has already been said, in fact I didn't even remember this
code on the mailing-list at all (too much traffic for me maybe).

Lionel