Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does each_slice with block and .map return nil

Why does this return nil and what does line 2 mean? The array represents rows of a Sudoku puzzle which I'm trying to create a solution for.

I'm trying different methods in irb to see how many different ways I can view the array.

array = ['015003002000100906270068430490002017501040380003905000900081040860070025037204600']
array.each_slice(9) { |e| puts e.map }
#<Enumerator:0x0000010288a470>
=> nil
like image 389
HandDisco Avatar asked Jan 28 '14 21:01

HandDisco


1 Answers

Some methods expect a block, and if block is not provided, they return Enumerable.

In your example, you invoked map without providing any block.

But you can call enumerable methods on enumerators. This allows you to change the behaviour of the iterators.

array[0].split('').each_slice(9).map { |el| el }

=> [["0", "1", "5", "0", "0", "3", "0", "0", "2"],
 ["0", "0", "0", "1", "0", "0", "9", "0", "6"],
 ["2", "7", "0", "0", "6", "8", "4", "3", "0"],
 ["4", "9", "0", "0", "0", "2", "0", "1", "7"],
 ["5", "0", "1", "0", "4", "0", "3", "8", "0"],
 ["0", "0", "3", "9", "0", "5", "0", "0", "0"],
 ["9", "0", "0", "0", "8", "1", "0", "4", "0"],
 ["8", "6", "0", "0", "7", "0", "0", "2", "5"],
 ["0", "3", "7", "2", "0", "4", "6", "0", "0"]]

It's one of slightly more advanced topics in Ruby but there are lot of resources in the internet, f.i. http://www.sitepoint.com/guide-ruby-collections-iii-enumerable-enumerator/

EDIT:

Just to answer the questions in the comment: You have only one long string in array. I don't ask why, but just to make some example, I needed actual array of (string?) numbers. array[0] takes this first element in array (the long string of numbers). When I have a string I can call String#split to get an array like `["0", "1", "5", "..."].

Array includes Enumerable module, thanks to that you can call methods like each_slice on it. As the docs state (http://rubydoc.info/stdlib/core/Enumerable:each_slice):

If no block is given, returns an enumerator

So after calling each_slice(9) I get Enumerator instance (http://rubydoc.info/stdlib/core/Enumerator). It has some own methods, but also includes Enumerable module (with methods like map, each_slice. Here's where the fun begins. If I call any of those methods on our enumerator (like map), it won't receive each element of array, like in normal case, but each element "returned" by enumerator, i.e. each single element is now array of 9 elements.

As always I highly recommend the Well Grounded Rubyist, where such subjects are thoroughly explained. http://www.manning.com/black2/

like image 73
Ernest Avatar answered Nov 16 '22 16:11

Ernest