2011-05-22 40 views

回答

1

我建議您不要在2D陣列中使用數組陣列,主要有三個原因。首先,它允許不一致:不是所有列(或行,請選擇)都需要具有相同的大小。其次,效率低下 - 你必須遵循兩個指針而不是一個指針。第三,存在很少的庫函數,這些函數透明且有效地用作二維數組的數組。

考慮到這些事情,您應該使用支持2D陣列的庫,例如scalala,或者您應該自己寫。如果你做後者,除其他外,這個問題神奇地消失。

所以就優雅而言:不,沒有辦法。但除此之外,你開始的路徑包含地段不雅;你可能會盡最大努力迅速離開它。

+0

我完全相信,scala編譯器神奇地將Array [Array]轉換爲真正的2D數組,因爲它受標準庫('Array.fill(n,dim,array)')支持。真是無賴。標準庫中沒有2D數組嗎? (Vector [Vector [_]] ;-) – 2011-05-23 06:03:18

+0

「真正的二維數組」是什麼意思? JVM不具有對多維數組的內置支持。 – 2015-12-26 16:48:19

+0

@SethTisue - 我假設一個「真正的二維數組」是一個M×N矩陣,大概是一個數據以行 - 主要順序存儲在內存中的地方,其中維是索引約定而不是單獨的數據結構。或者,它可能是一個數組的數組,其維度被鍵入爲相同的(如果您有一個類型化的大小參數,則正常數組不會)。關鍵屬性是對於'a(i)(j)',索引'j'中的入/出界限不依賴於'i'。 (這是一個2D數組,例如C++。) – 2015-12-26 22:41:25

1

你只需要isDefinedAt檢查索引i數組,如果它存在:

def do_to_elt(i:Int, j:Int): Unit = 
    if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j)) 

編輯:錯過關於優雅的解決方案的一部分,因爲我的代碼集中在錯誤的編輯前。

關於優雅:不,本身沒有辦法以更優雅的方式表達它。有些人可能會告訴你使用pimp-my-library -Pattern使它看起來更優雅,但實際上它不在這種情況下。

如果您的唯一用例是在索引有效時使用多維數組的元素執行函數,那麼此代碼會執行該操作,您應該使用它。你可以通過改變簽名概括的方法取功能應用到元素,也許值,如果索引無效這樣的:

def do_to_elt[A](i: Int, j: Int)(f: Int => A, g: => A =()) = 
    if (a.isDefinedAt(i) && a(i).isDefinedAt(j)) f(a(i)(j)) else g 

,但我不會改變任何事情不止於此。這看起來並不更優雅,但卻拓寬了用例。

(另外:如果您在使用數組時,你主要做性能方面的原因而在這種情況下,它甚至可能會更好,不使用isDefinedAt但進行基於陣列的長度有效性檢查。)

+0

是的,這就是我所做的。我希望有更優雅的東西。 – 2011-05-22 21:55:59