Scala row range
In Ruby, we can do this:
$ irb >> ("aa".."bb").map { |x| x } => ["aa", "ab", "ac", "ad", "ae", "af", "ag", "ah", "ai", "aj", "ak", "al", "am", "an", "ao", "ap", "aq", "ar", "as", "at", "au", "av", "aw", "ax", "ay", "az", "ba", "bb"] In Scala, if I try the same to get the error:
$ scala Welcome to Scala version 2.9.1 (OpenJDK 64-Bit Server VM, Java 1.7.0_51). scala> ("aa" to "bb").map(x => x) <console>:8: error: value to is not a member of java.lang.String ("aa" to "bb").map(x => x) ^ How to get row range in Scala?
In this example you can do (scala 2.10)
val atoz = 'a' to 'z' for {c1 <- atoz if c1 <= 'b'; c2 <- atoz if (c1 == 'a' || (c1 == 'b' && c2 < 'c'))} yield s"$c1$c2" Edited according to the comment, thanks (but getting a little ugly!)
('a' to 'z').map("a" + _) :+ "ba" :+ "bb" :)
And for understanding it will be nice:
val abc = 'a' to 'z' for (c1 <- abc; c2 <- abc) yield (s"$c1$c2") This gives Seq / Vector [String] with all the permutations you expect
Here is one possibility, assuming your characters should be in the range from 'a' to 'z'. The intToAlpha function intToAlpha not very pretty and is not symmetrical with alphaToInt , so you can find a better implementation.
// "a" -> 0, "b" -> 1, "ba" -> 26, "bb" -> 27 etc. def alphaToInt(s: String) = (0 /: s) { (res, c) => res * 26 + c - 'a' } // reverse function to `alphaToInt` def intToAlpha(len: Int)(i: Int) = { val sb = new StringBuilder var j = i while (sb.length < len) { sb append ((j % 26) + 'a').toChar j /= 26 } sb.reverse.toString } def range(from: String, to: String) = alphaToInt(from) to alphaToInt(to) map intToAlpha(from.length) Test:
range("aa", "bb") Alternative version:
import annotation.tailrec @tailrec def intToAlpha(len: Int, res: String = "")(i: Int): String = if (len <= 0) res else { val c = ((i % 26) + 'a').toChar intToAlpha(len - 1, s"$c$res")(i / 26) } This is like a 26 * 26 matrix for each 2 char combination, we have a matrix (az * az):
def scan(start:String, end:String) = { val row_start = start.toCharArray.head val column_start_of_first_row = start.toCharArray.last val row_end = end.toCharArray.head val column_end_of_last_row = end.toCharArray.last val printRow = (current_row:String, current_row_start_col:Char, current_row_end_col:Char) => (current_row_start_col to current_row_end_col).map( current_row + _ ) (row_start to row_end).map { current_row=> current_row match { case `row_start` => printRow(current_row.toString, column_start_of_first_row, 'z') case `row_end` => printRow(current_row.toString, 'a' , column_end_of_last_row) case _ => printRow(current_row.toString, 'a' , 'z') } }.reduce(_ ++: _) } println( scan("aa", "bb") ) println( scan("af", "bb") )