In Ruby this works fine, and as expected:
rangeres.each_cons(2).map { |n1, n2| n2 - n1 }.tally.sort
It takes an array of numbers (increasing +ints), finds the diff between each pair,
tallys their values into hash pairs, then sorts them in ascending order per the keys.
Here’s sample output:
> print rangeres.each_cons(2).map { |n1, n2| n2 - n1 }.tally.sort
=> [[2, 291946], [4, 291658], [6, 507719], [8, 220068], [10, 282635], [12, 351830], [14, 190819], [16, 139980]]
But the same code produces this error in Crystal (1.6.1):
In rangeres.cr:6:29
6 | print rangeres.each_cons(2).map { |n1, n2| n2 - n1 }.tally.sort
^--
Error: wrong number of block parameters (given 2, expected 1)
OK, a little surprising, so after looking at the docs, I tried this and got:
In rangeres.cr:6:62
6 | print rangeres.each.cons_pair.map { |n1, n2| n2 - n1 }.tally.sort
^---
Error: undefined method 'sort' for Hash(Int32, Int32)
Ok, map
works now, and sort
is the problem, so getting rid of it for now works:
This produces unsorted output.
print rangeres.each.cons_pair.map { |n1, n2| n2 - n1 }.tally
After reading the Docs again, I got the other form to work too:
print rangeres.each_cons(2).map { |pair| pair[1] - pair[0] }.tally.
I finally got around the sort
issue from experience with Crystal.
It wants an array
, so I gave it an array
.
print rangeres.each_cons(2).map { |pair| pair[1] - pair[0] }.tally.to_a.sort
Now I’m not saying Crystal had the problems to get this snippet to finally work.
After I took the time to search for, and read, the docs it was clear what to do.
However, compared to Ruby it was sooooo unituitive what the Crystal syntax had to be.
I share this story, because like it not, Life Is Unfair!
I took at least 30 minutes to figure this out, because I knew Crystal could do this too.
I just needed to know how it did it. Then I took another hour to write this up.
Because Crystal is the yougin on the block, it’s going to be compared to older siblings,
and for Crystal that’s mostly (firstly) going to be Ruby. And small little differences
between them like this may turn the not so invested potential user away, because they
ain’t going to go thru the trouble of tracking the Docs down and reading them.
So please, if possible, somewhere in the Docs put this example as something to be aware
of, for both people coming from Ruby to Crystal, and vice versa.
But…I think sort
should work with hashes the same way Ruby does. It should be easy to do.
Maybe for 2.0 (or sooner) you can consider and include that behavior.
ADD:
Ah…I just remembered, from a long ago prior problem, this works too. Still not intuitively to do.
print rangeres.each.cons(2).map { |(n1, n2)| n2 - n1 }.tally.to_a.sort