2015-08-21 15 views
7

Tôi muốn tạo ra một sự kết hợp của một số giá trị như trong đoạn code dưới đây:Idiomatic Scala cách kết hợp tạo ra uể oải

object ContinueGenerate { 

    val foods = List("A", "B", "C") 
    val places = List("P1", "P2", "P3") 
    val communities = List("C1", "C2", "C3", "C4") 

    case class Combination(food: String, place: String, community: String) 

    def allCombinations() = { 
    for { 
     food <- foods; place <- places; community <- communities 
    } yield Combination(food, place, community) 
    } 

    def main(args: Array[String]) { 
    allCombinations foreach println 
    } 

} 

Tuy nhiên, vấn đề với phương pháp này là, tất cả các dữ liệu được tạo ra cùng một lúc. Đây là vấn đề lớn khi kích thước của foods, placescommunities trở nên rất lớn. Cũng có thể có các thông số khác ngoài ba thông số này.

Vì vậy, tôi muốn có thể tạo kết hợp, theo kiểu tiếp tục, sao cho kết hợp chỉ được tạo khi được yêu cầu.

Điều gì sẽ là một cách Scala thành ngữ để làm điều đó?

Trả lời

4

Bạn có thể thực hiện việc này bằng cách sử dụng View trên mỗi danh sách. Trong đoạn code dưới đây tôi đã thêm một hiệu ứng phụ để nó có thể nhìn thấy khi các yield được gọi cho mỗi phần tử.

val foods = List("A", "B", "C") 
val places = List("P1", "P2", "P3") 
val communities = List("C1", "C2", "C3", "C4") 

case class Combination(food: String, place: String, community: String) 

def allCombinations() = 
    for { 
    food <- foods; place <- places; community <- communities 
    } yield { 
    val comb = Combination(food, place, community) 
    println(comb) 
    comb 
    } 

//Prints all items 
val combinations = allCombinations() 

def allCombinationsView() = 
    for { 
    //Use a view of each list 
    food <- foods.view; place <- places.view; community <- communities.view 
    } yield { 
    val comb = Combination(food, place, community) 
    println(comb) 
    comb 
    } 
//Prints nothing 
val combinationsView = allCombinationsView() 

//Prints 5 items 
val five = combinationsView.take(5).toList 
7

Bạn sử dụng các dòng:

object ContinueGenerate { 

    val foods = Stream("A", "B", "C") 
    val places = Stream("P1", "P2", "P3") 
    val communities = Stream("C1", "C2", "C3", "C4") 

    case class Combination(food: String, place: String, community: String) 

    def allCombinations() = { 
    for { 
     food <- foods; place <- places; community <- communities 
    } yield Combination(food, place, community) 
    } 

    def main(args: Array[String]) { 
    allCombinations foreach println 
    } 

} 

Một Stream cache tất cả các dữ liệu. Nếu bạn chỉ muốn lặp lại một lần, hãy sử dụng Iterator thay vào đó, sẽ thu thập rác để thu thập các phần tử đã đi qua.

Các vấn đề liên quan