From: Josh Cheek Date: 2013-05-19T21:16:24+09:00 Subject: Re: Need help to understand the Enumerable methods --001a11c37c441ce11804dd112f39 Content-Type: text/plain; charset=ISO-8859-1 On Sun, May 19, 2013 at 4:03 AM, Love U Ruby wrote: > I am very eager to know about the Enum#sort{|a,b|..} > > http://www.ruby-doc.org/core-2.0/Enumerable.html#method-i-sort > > Now my question is about the internal mechanism. > > ***Returns an array containing the items in enum sorted, either > according to their own <=> method, or by using the results of the > supplied block. The block should return -1, 0, or +1 depending on the > comparison between a and b.** > > I took the below as an example: > > dogs = [ > { name: "Rover", gender: "Male" }, > { name: "Max", gender: "Male" }, > { name: "Fluffy", gender: "Female" }, > { name: "Cocoa", gender: "Female" } > ] > > # gender asc, name asc > p(dogs.sort do |a, b| > [a[:gender], a[:name]] <=> [b[:gender], b[:name]] > end) > #=> [{:name=>"Cocoa", :gender=>"Female"}, {:name=>"Fluffy", > :gender=>"Female"}, {:name=>"Max", :gender=>"Male"}, {:name=>"Rover", > :gender=>"Male"}] > > My question is using the method `<=>` returns value `-1,0,+1`,how the > method sorting the source array ? What the things are actually going on > with the result of `<=>`? > > -- > Posted via http://www.ruby-forum.com/. > > The spaceship operator (<=>) returns a negative number if the value on the left is less than the value on the right, 0 if they are equal, and a positive number if the value on the left is more than the value on the right. 'a' <=> 'b' # => -1 'b' <=> 'b' # => 0 'c' <=> 'b' # => 1 So the sort method just checks for these to see which element should go first. Something like this: def sort(unsorted_ary, &comparison) comparison ||= lambda { |a, b| a <=> b } unsorted_ary.each_with_object [] do |to_add, sorted| index = sorted.index { |already_added| 0 < comparison.call(already_added, to_add) } sorted.insert (index || -1), to_add end end sort([*1..10].shuffle) { |a, b| a <=> b } # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] sort([*1..10].shuffle) { |a, b| b <=> a } # => [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] sort([*1..10].shuffle) # => [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] sort([*1..10].shuffle) do |a, b| a.even? && b.even? ? b <=> a : a.odd? && b.odd? ? a <=> b : a.even? ? -1 : 1 end # => [10, 8, 6, 4, 2, 1, 3, 5, 7, 9] --001a11c37c441ce11804dd112f39 Content-Type: text/html; charset=ISO-8859-1 Content-Transfer-Encoding: quoted-printable On Sun, May 19, 2013 at 4:03 AM, Love U Ruby <lists@ruby-forum.com= > wrote:
I am very eager to know about the Enum#sort{|a,b|..}

http://www.ruby-doc.org/core-2.0/Enumerable.html#method-i= -sort

Now my question is about the internal mechanism.

***Returns an array containing the items in enum sorted, either
according to their own <=3D> method, or by using the results of the supplied block. The block should return -1, 0, or +1 depending on the
comparison between a and b.**

I took the below as an example:

dogs =3D [
=A0 { name: "Rover", gender: "Male" },
=A0 { name: "Max", gender: "Male" },
=A0 { name: "Fluffy", gender: "Female" },
=A0 { name: "Cocoa", gender: "Female" }
]

# gender asc, name asc
p(dogs.sort do |a, b|
=A0 [a[:gender], a[:name]] <=3D> [b[:gender], b[:name]]
end)
#=3D> [{:name=3D>"Cocoa", :gender=3D>"Female"}= , {:name=3D>"Fluffy",
:gender=3D>"Female"}, {:name=3D>"Max", :gender=3D= >"Male"}, {:name=3D>"Rover",
:gender=3D>"Male"}]

My question is using the method `<=3D>` returns value `-1,0,+1`,how t= he
method sorting the source array ? What the things are actually going on
with the result of `<=3D>`?

--
Posted via http://= www.ruby-forum.com/.


The spaceship operator (<=3D&g= t;) returns a negative number if the value on the left is less than the val= ue on the right, 0 if they are equal, and a positive number if the value on= the left is more than the value on the right.

'a' <=3D> 'b' =A0# =3D> -= 1
'b' <=3D> 'b' =A0# =3D> 0
&#= 39;c' <=3D> 'b' =A0# =3D> 1

=

So the sort method just checks for these to see which element should g= o first. Something like this:

def sort(unsort= ed_ary, &comparison)
=A0 comparison ||=3D lambda { |a, b| a &= lt;=3D> b }
=A0=A0
=A0 unsorted_ary.each_with_object [] do |to_add, sort= ed|
=A0 =A0 index =3D sorted.index { |already_added| 0 < compa= rison.call(already_added, to_add) }
=A0 =A0 sorted.insert (index = || -1), to_add
=A0 end
end


sort([*1..10].shuffle) { |a, b| a <=3D> b } =A0# =3D> [1, 2, 3,= 4, 5, 6, 7, 8, 9, 10]
sort([*1..10].shuffle) { |a, b| b <=3D&= gt; a } =A0# =3D> [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
sort([*1..10].shuffle) =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 # =3D&g= t; [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
sort([*1..10].shuffle) do |a, = b|=A0
=A0 a.even? && b.even? ? b <=3D> a :
=A0 a.odd? =A0&& b.odd? =A0? a <=3D> b :
=A0 a.even? =A0 =A0 =A0 =A0 =A0 =A0? -1 =A0 =A0 =A0:
=A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A01
end =A0 =A0 =A0 =A0 =A0= =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0# =3D> [10, = 8, 6, 4, 2, 1, 3, 5, 7, 9]

--001a11c37c441ce11804dd112f39--