2017-02-22 11 views
0

我需要在我的代碼中將TV評級(針對電視節目)轉換爲該評級的案例對象。因此,我有一個匹配的情況下,像這樣:基於算法的大小寫匹配字符串。我應該使用哪種算法?

def fromString(s: String): Option[TvRating] = s.toLowerCase match { 
    case "tvy" | "tv-y" | "tv y" | "y" => Some(tvY) 
    case "tvg" | "tv-g" | "tv g" | "g" => Some(tvG) 
    case "tvpg" | "tv-pg" | "tv pg" | "pg" => Some(tvG) 
    case "tv14" | "tv-14" | "tv 14" | "14" => Some(tv14) 
    case "tvma" | "tv-ma" | "tv ma" | "ma" => Some(tvMA) 
    case _ => Some(noTvRating) 
} 

正如你可以看到我試圖相互匹配的評價,這是麻煩的所有排列,仍然不能解釋像「tv.14」或「成熟的觀衆」。

是否有像soundX這樣的算法,但對於像這些評級那樣的代碼,我可以用作最後的手段。然後我的代碼將如下所示:

def fromString(s: String): Option[TvRating] = s.toLowerCase match { 
    case "tvy" | "tv-y" | fancyAlgo(s, "tv-y") => Some(tvY) 
    case "tvg" | "tv-g" | fancyAlgo(s, "tv-g") => Some(tvG) 
    case "tvpg" | "tv-pg" | fancyAlgo(s, "tv-pg") => Some(tvG) 
    case "tv14" | "tv-14" | fancyAlgo(s, "tv-14") => Some(tv14) 
    case "tvma" | "tv-ma" | fancyAlgo(s, "tv-ma") => Some(tvMA) 
    case _ => Some(noTvRating) 
} 

或者我可以使這些匹配更健壯的任何其他建議。由於tv-g不是像「狗」或「馬」這樣的詞,我不能基於音頻或類似的聲音文字。

這是評級的一個例子。還有其他的比賽。這裏是另一個例子星級(如腐爛的番茄的電影評級)

def fromString(s: String): Option[StarRating] = s.toLowerCase match { 
    case "1" | "one star" | "one stars" => Some(oneStar) 
    case "1.5" | "1.5 stars" | "one and a half stars" => Some(oneAndHalfStar) 
    case "2" | "2 stars" | "two stars" => Some(twoStars) 
    case "2.5" | "2.5 stars" | "two and a half stars" => Some(twoAndHalfStars) 
    case "3" | "3 stars" | "three stars" => Some(threeStars) 
    case "3.5" | "3.5 stars" | "three and a half stars" => Some(threeAndHalfStars) 
    case "4" | "4 stars" | "four stars" => Some(fourStars) 
    case _ => Some(noStars) 
} 

乾杯!

+0

是模糊的字符串匹配我在找什麼? – dlite922

+0

我明白你的意思了,但我認爲(一般來說)你要求幾乎不可能 - 匹配任何意思(比如說)「pg」但沒有規定某些意思是「pg」的規則。這不是模糊的字符串匹配,因爲它與*無法匹配什麼,如果你可以給出更多關於什麼可以匹配的細節,比如說「tv-14」(例如,應該「十四」匹配嗎?被完成 –

+0

'Option []'類型的整點是_might_是'None'。爲什麼你的例子沒有'None'條件? – jwvh

回答

2

轉到數據驅動:

val ratings = scala.collection.mutable.Map[String, String]() withDefaultValue "noTVRating" 

type TvRating = String 

def addRatingStyle(base:String, result:String) = { 
    val suffix = base.stripPrefix("tv") 
    ratings += ("tv"+suffix->result) 
    ratings += ("tv-"+suffix->result) 
    ratings += ("tv "+suffix->result) 
    ratings += (suffix->result) 
} 

addRatingStyle("tvy", "tvy") 
addRatingStyle("tvg", "tvg") 
addRatingStyle("tvpg", "tvpg") 
addRatingStyle("tv14", "tv14") 
addRatingStyle("tvma", "tvma") 


def fromString(s: String): Option[TvRating] = Some(ratings(s.toLowerCase)) 
+0

upvoted因爲有趣的解決方案,但沒有解決我的匹配問題。問題是我不知道前綴是否總是「」,「 - 」或「」。否則,我的原始匹配工作不會爲程序員增加上述的上下文過載。雖然具有創造性,但它不使用算法來找到「最佳」匹配。 – dlite922

2

使用case object s到與unapply方法定義自己的收視率。一個簡單的正則表達式可能會處理其餘的:

sealed trait TVRating 

case object Youth extends TVRating { 
    def unapply(s: String): Option[TVRating] = { 
    //insert fancier match logic here... 
    if(s.matches("tv.*y") || s.equals("y")) { 
     Some(Youth) 
    } else { 
     None 
    } 
    } 
} 

case object General extends TVRating { 
    def unapply(s: String): Option[TVRating] = { 
    //insert fancier match logic here... 
    if(s.matches("tv.*g")) { 
     Some(Youth) 
    } else { 
     None 
    } 
    } 
} 

object Main extends App { 

    override def main(args: Array[String]) = { 
    "tv.y" match { 
     case Youth(s) => println("Youth") 
     case General(s) => println("General") 
     case _ => println("Unknown") 
    } 
    } 
} 
+0

我一直忘記不適用。這是一個很酷的解決方案!只有我看到的是,正則表達式並不在一個地方讓我看到或添加到它們中。問題:在'def main'前面覆蓋了什麼? – dlite922

+0

這個答案說明了爲什麼我在上面評論說OP正在尋求一些幾乎不可能的事情(儘管答案本身並不是問題)。請注意,General也與PG匹配。 Soundex工作的原因在於,從拼寫單詞到聲音的映射有相當好的理解,雖然語音(儘管如此,由於通常的奇怪的英語問題,會有許多誤報和否定)。而且有人傾向於使用Soundex來進行「足夠好」的匹配,而不是「必須分類到正確的桶」,這裏需要什麼。 –