2014-04-02 96 views
7

在Ruby中,我們可以這樣做:字符串範圍斯卡拉

$ 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"] 

在Scala中,如果我嘗試同樣的,我得到的錯誤:

$ 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) 
        ^

如何獲得一定範圍內的字符串在Scala呢?

+5

一個相當奇怪的行爲。 Ruby如何確定你想停留在字符'z'? –

+0

Infact'(「aB」..「bZ」)。map {| x | x}知道它必須停在'Z'處。 '( 「A0」 .. 「B9」)地圖{|。X | x}知道它必須停在'9'處。所以必須有一些能夠提供這種邏輯的字母和數字範圍。 – tuxdna

回答

3

在這個例子中,你可以做(​​斯卡拉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" 

市價修改意見,感謝(但變得有點難看!)

+1

我想補充的限制像'C1 < - ATOZ如果c1 <=「b''它配不配的問題 – n1ckolas

+0

的初始條件,您會考慮以下一個‘乾淨’的解決方案? 'def charval(x:Char,y:Char)= x * 1000 + y'和'for {c1 < - atoz; C2 < - ATOZ如果(charval(C1,C2)<= charval( 'B', 'B'))}產量的 「$ $ C1 C2」'。更像數學,但用另一個結尾字符串「bk」替換「bb」變得更容易。更具可讀性 – mesutozer

1
('a' to 'z').map("a" + _) :+ "ba" :+ "bb" 

:)

+6

這就是爲什麼我在代碼後面微笑的原因 – ZhekaKozlov

-1

這裏一種可能性,假設你的角色應該在'a'到'z'的範圍內。該intToAlpha功能不是很漂亮,不是對稱alphaToInt,所以人們可能會拿出一個更好的實現。

// "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) 

測試:

range("aa", "bb") 

另一種版本:

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) 
    } 
-1

它像一個26 * 26矩陣,每2字符組合,IMAGIN我們有一個矩陣(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")) 
1

A理解會做很好:

val abc = 'a' to 'z' 
for (c1 <- abc; c2 <- abc) yield (s"$c1$c2") 

這將產生一個序列/矢量[字符串]的所有排列你期望