Sorting Method

books = ["Charlie and the Chocolate Factory", "War and Peace", "Utopia", "A Brief History of Time", "A Wrinkle in Time"]

# To sort our books in ascending order, in-place
books.sort! { |firstBook, secondBook| firstBook <=> secondBook }

# Sort your books in descending order, in-place below

books.sort! do |first,second| first
    first <=> second
end
books.reverse!

I’ve learned sorting method and I understand variables and what not. But I don’t understand why |first,second| and first exist. Can that whole line be explained? Obviously first and second are local variables (to the method) but those are defined in ||. Why is that second “first” there? How does this sort one by one? Most thorough explanation possible please.

Sorting Algorithms is a pretty complicated subject.

Wiki Sorting

No I do not want to know about the actual sorting algorithm. I wanted to know why the varibles are used in such inside the sorting method.

Explain how the |first,second| first

^ Explain why that is so. I thought variables for methods are defined in the | | section? If that’s true, why is there a second first?

How does that makes any sense? Explain that entire method to me.

I’m not asking about the underlying programming. I’m talkin about what is front of your eyes.

I’m not asking about the underlying programming. I’m talkin about what is front of your eyes.

I misunderstood, I thought you were asking about both.

I still suggest reading through the wiki.

So let me get this straight. When sorting you 100% always need TWO sorting variables (assumption made here that you always need 2)

The |first,second| are our variables that we will be sorting in the <=> operator (returns -1, 0 ,1 depdending on which one should be sorted first (-1 for “first”, 0 if they are the same, and 1 if “second” should be sorted first)

The |first, second| first tells the program that if first SHOULD be sorted first, then put first first? If the bolded there was “second” then it would tell the program "if first should be sorted over second, put second first (weird but logically that would work right?)

How is that logic?

Hmm no that can’t be right. I changed the second and first around (the one after | |) and codecademy exercise returned the same result. I’m confused. Explanation please.

No idea. I don’t do ruby.

$10 says @markbrown4 knows the answer.

Hold up HOLD UP HOLD UP. I remove that second “first” instance AND THE PROGRAM STILL RUNS? What is this sorcery. Why do I even NEED that then? DO I?

Second question - I have the sort method…why do I also need <=> in there?

sort_by takes an array or a Hash (whatever) and sorts based on number or string or whatever. I get that.

Does sort ALWAYS have instance of <=> since that’s what the sort method relies on to sort crap? Just want to know if the sort univnersally will use <=>

Edit-I feel like that second instance after | | was poor reading from their example program. Weird it still let me work with it. I fully understand sort now except for my above question in the above paragraph.

That first hanging off the first line shouldn’t be there.

To help you understand it this is the equivalent javascript code

books.sort!(function(first, second) {
  return first < second
});

The parameters between the pipes are the arguments to the block or function.
Blocks can either be between do and end or curlies { }

You don’t need any of this for sorting strings / numbers. Without a block they’ll sort alphabetically and numerically. You only need to provide a block if you’re sorting more complicated objects where you want to compare specific properties.

books.sort!

In those cases you always need two parameters to compare each item against.

<=> is a the Combined comparison operator. Returns 0 if first operand equals second, 1
if first operand is greater than the second and -1 if first operand is
less than the second.

Understood. sort! will take care of simple stuff. sort with the inner code will be for more complex.
sort_by ismore for arrays and Hashes?

Will more complex objects always need to be compared with <=>? Is that the only way? Or should I wait for possible later comparisons in a later tutorial?

Edit-Yes I understand the -1,0,1 part. Just curious about how universal it’s used in sort for objects/complex things.

Then you know the answer already, if you don’t want to use the compare operator you can return 0, -1, 1 manually.

I meant more along the lines of, is that the ONLY way to sort other complex objects? Are there others? Or if I will be sorting more complex objects, <=> is a one stop shop.

Yes, use the compare operator to compare things.

books = [{
  id: 10,
  name: "Ten things"
},{
  id: 15,
  name: "Fifteen things"
}]
books.sort! { |first,second| first[:id] <=> second[:id] }
=> [{:id=>10, :name=>"Ten things"}, {:id=>15, :name=>"Fifteen things"}]
books.sort! { |first,second| first[:name] <=> second[:name] }
=> [{:id=>15, :name=>"Fifteen things"}, {:id=>10, :name=>"Ten things"}]

That’s a lot to look at. So it can compare sorts that we compare with compare. But basically <=> is the one stop shop. Thanks @markbrown4, I understand. Not sure why that second “first” was in my original code and codecademy allowed it to run. I got it working and went back over WHY it worked and I couldn’t for the life of me figure out why the sorting worked. Turns out it just had an extra word. Codecademy isn’t perfect I guess. Thank you!

Real quick - I learned that as of Ruby 1.9, doing Hashes (with symbols) in the form of

:symbol_here => “value” is no longer supported. Should I universally bedoing the below (and retain the previous information when reading other peoples outdated code?)

symbol_here: “value”

The old hash rocket syntax still works.

hash = { :still => 'works' }

The new syntax is just simpler, javascript’s hash syntax seems to winning everywhere. It makes sense to go with this.

hash = { still: 'works' }

So it just comes down to personal preference? No difference at all? I personally like the “new” syntax because it’s what I recognize from Javascript.

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.