07-19-2023, 12:42 AM
I think this is a great Ruby one-liner:
someArray.sort_by {rand}
It's concise, it's readable, and it works - but I don't quite understand how. Here's what I know:
1. `rand` evaluates to a number between 0 and 1 (like 0.783468632804653)
2. `rand` is being repeatedly evaluated in the code above, because assigning it to `x` first breaks the random sort
3. `sort_by {0.783468632804653}`, or any other number I tried, has no effect on the array
ruby-doc.org wasn't much help to me [in this case][1].
Can someone explain this step-by-step?
[1]:
## Update
I've been using Ruby longer now, and I see that I was missing a concept or two here. The key thing is that:
1. `rand` is a method (defined on Kernel); it generates a random number
2. `{rand}` is a block, which `sort_by` keeps, calling it **each time** it wants to compare two items in the collection. If the collection is a bunch of objects representing countries, it needs to be able to grab two of them and determine which one comes first. Do you put the one with the longest name first? The one with the largest land mass? The block should answer that question by returning a value that says "you asked about Spain vs Cameroon, and I say Cameroon comes first." (You could do that with `{|country| country.name.length}`
The rest of how `sort_by` works is explained in the documentation. I'm still not quite sure why returning a random number works at all - presumably `sort_by` rounds it to -1, 0, or 1, whichever is closest? But in any case, getting a **different random number** every time you call the block is quite different from getting the **same number** every time. When `sort_by` says "which of these two countries comes first?", `{rand}` puts on a blindfold, turns around 10 times, points and says "that one!" :)
someArray.sort_by {rand}
It's concise, it's readable, and it works - but I don't quite understand how. Here's what I know:
1. `rand` evaluates to a number between 0 and 1 (like 0.783468632804653)
2. `rand` is being repeatedly evaluated in the code above, because assigning it to `x` first breaks the random sort
3. `sort_by {0.783468632804653}`, or any other number I tried, has no effect on the array
ruby-doc.org wasn't much help to me [in this case][1].
Can someone explain this step-by-step?
[1]:
[To see links please register here]
## Update
I've been using Ruby longer now, and I see that I was missing a concept or two here. The key thing is that:
1. `rand` is a method (defined on Kernel); it generates a random number
2. `{rand}` is a block, which `sort_by` keeps, calling it **each time** it wants to compare two items in the collection. If the collection is a bunch of objects representing countries, it needs to be able to grab two of them and determine which one comes first. Do you put the one with the longest name first? The one with the largest land mass? The block should answer that question by returning a value that says "you asked about Spain vs Cameroon, and I say Cameroon comes first." (You could do that with `{|country| country.name.length}`
The rest of how `sort_by` works is explained in the documentation. I'm still not quite sure why returning a random number works at all - presumably `sort_by` rounds it to -1, 0, or 1, whichever is closest? But in any case, getting a **different random number** every time you call the block is quite different from getting the **same number** every time. When `sort_by` says "which of these two countries comes first?", `{rand}` puts on a blindfold, turns around 10 times, points and says "that one!" :)