2011-07-30 24 views
2

我在Scala編程第23.5節中看到,map,flatMap和filter操作總是可以轉換爲for-comprehensions,反之亦然。將一系列的地圖操作轉換爲理解

我們給出以下等價:

def map[A, B](xs: List[A], f: A => B): List[B] = 
    for (x <- xs) yield f(x) 

我有一系列的地圖操作的計算出的值:

val r = (1 to 100).map{ i => (1 to 100).map{i % _ == 0} } 
        .map{ _.foldLeft(false)(_^_) } 
        .map{ case true => "open"; case _ => "closed" } 

我不知道這將是什麼樣的了-理解。我如何翻譯它?

(如果它是有幫助的,在的話是這樣的:從1到100

  • 每個

    • 取整數,創建100個布爾值
    • 每個列表與XOR運算摺疊的列表,回一個布爾
    • 產量取決於布爾

    我想有一個100個字符串「打開」列表或「關閉」是一個獨立的ard翻譯地圖操作的方式以及其中實際功能的細節並不重要。我可能是錯誤的。)

  • 回答

    6

    這是你正在尋找的翻譯類型?

    for (i <- 1 to 100; 
        val x = (1 to 100).map(i % _ == 0); 
        val y = x.foldLeft(false)(_^_); 
        val z = y match { case true => "open"; case _ => "closed" }) 
        yield z 
    

    如果需要的話,在x定義中的map也可轉換爲一個「內部」換理解。

    回想起來,一系列鏈式map電話是有點微不足道,因爲你可以等效地由函數調用map一次:

    s.map(f).map(g).map(h) == s.map(f andThen g andThen h) 
    

    我找到-內涵是一個更大的勝利時flatMap和涉及filter。考慮

    for (i <- 1 to 3; 
        j <- 1 to 3 if (i + j) % 2 == 0; 
        k <- 1 to 3) yield i^j^k 
    

    (1 to 3).flatMap { i => 
        (1 to 3).filter(j => (i + j) % 2 == 0).flatMap { j => 
        (1 to 3).map { k => i^j^k } 
        } 
    } 
    
    +0

    這是有用的,謝謝。我可以通過將所有內容放在'yield'部分中去除多個映射,而不需要中間變量,因此:'val r = for(i <-1 to 100)yield(1 to 100).map(i% _ == 0).foldLeft(false)(_^_)match {case true =>「open」;案件_ =>「關閉」}'。 (我也嘗試過'和然後',但有點混亂。) –