2012-12-13 89 views
2

在適當的功能方式下,Scala中以Java代碼執行以下代碼的最佳方式是什麼?Scala最佳實踐:映射2D數據

LinkedList<Item> itemsInRange = new LinkedList<Item>(); 
for (int y = 0; y < height(); y++) { 
    for (int x = 0; x < width(); x++) { 
     Item it = myMap.getItemAt(cy + y, cx + x); 
     if (it != null) 
      itemsInRange.add(it); 
    } 
} 

// iterate over itemsInRange later 

在過程中,它可以直接在命令式的方式轉化爲斯卡拉:

val itemsInRange = new ListBuffer[Item] 
for (y <- 0 until height) { 
    for (x <- 0 until width) { 
     val it = tileMap.getItemAt(cy + x, cx + x) 
     if (!it.isEmpty) 
      itemsInRange.append(it.get) 
    } 
} 

,但我想這樣做的正確的,功能性的方式。

我推測在某種2D範圍上應該有map的操作。理想情況下,map將執行一個函數,該函數將獲得xy作爲輸入參數並輸出Option[Item]。之後,我會得到類似Iterable[Option[Item]]flatten的東西,它會產生Iterable[Item]。如果我是對的,唯一缺少的難題就是以某種方式在2D範圍內進行地圖操作。

回答

7

你可以做到這一切在一個很好的一步:

def items[A](w: Int, h: Int)(at: ((Int, Int)) => Option[A]): IndexedSeq[A] = 
    for { 
    x <- 0 until w 
    y <- 0 until h 
    i <- at(x, y) 
    } yield i 

現在比方說我們有符號在四乘四板這種表示:

val tileMap = Map(
    (0, 0) -> 'a, 
    (1, 0) -> 'b, 
    (3, 2) -> 'c 
) 

我們只是寫:

scala> items(4, 4)(tileMap.get) 
res0: IndexedSeq[Symbol] = Vector('a, 'b, 'c) 

我認爲是你想要的。

+0

謝謝!看起來這正是我正在尋找的!這些「產量」的東西看起來很有希望! – GreyCat