2013-09-28 35 views
1

這是2D陣列:取(X,Y),其中條件匹配

int[][] array2D = new int[7][]; 
for (int i = 0; i < 7; i++) 
    array2D[i] = new int[7]; 

如何可以把以下到LINQ查詢,或者使用可枚舉的方法來實現相同的輸出?

var lst = new List<Point>(); 

for (int r = 0; r < array2D.Length; r++) 
    for (int c = 0; c < array2D[r].Length; c++) 
     if (array2D[r][c] == 0) 
      lst.Add(new Point(c, r)); 

編輯 - 基於解決方案@「王中王的回答

var lst = m_boardArr.SelectMany((row, rowIndex) => 
      row.Select((val, colIndex) => 
       new { val, point = new Point(colIndex, rowIndex) }) 
        .Where(col => col.val == 0) 
        .Select(col => col.point)).ToList(); 

回答

1

試試這個:

var lst = array2D.SelectMany((x,r) => x.Select((a,c)=> new {a,b=new Point(c,r)}) 
             .Where(a=>a.a==0) 
             .Select(a=>a.b)).ToList(); 
+0

這將不起作用:c循環變量在已過濾的行上運行,並且不會反映原始數組的索引。 – CSJ

+0

@CSJ你說得對,有點小錯。 –

+1

大量的編輯,但你最終得到它:)這是最緊湊的答案。我喜歡這個。 – Nayan

1
var lst = array2D 
    .SelectMany((innerArray, r) 
     => Enumerable 
       .Range(0, innerArray.Length) 
       .Where(c => innerArray[c] == 0) 
       .Select(c => new Point(c, r))) 
    .ToList(); 

不過,您目前的解決方案是更具可讀性。

+0

您的第一個答案有效,但第二個答案不可編,因爲Point是結構,而不是類。所以,你不能輸入一個null來指向Point。謝謝! – Nayan

+0

@Nayan對。我刪除了錯誤的版本。 – BartoszKP

1

訣竅是使用SelectSelectMany可捕捉到循環變量到匿名類型,然後讓這些屬性回來以後Where條款之後,即:

var list = array2D 
    .SelectMany((row, r) => row 
     .Select((el, c) => 
     new {Element = el, ColIndex = c, RowIndex = r}) 
     .Where(thing => thing.Element == 0) 
     .Select(thing => new Point(thing.RowIndex, thing.ColIndex))) 
    .ToList(); 

編輯:Bartosz的評論也適用於此解決方案。不可讀!

+0

你的解決方案給出了幾乎正確的答案......實際上,你交換了x和y。所以,該列表包含'Point(y,x)'數據。不過,數值是正確的。 – Nayan

+0

我認爲'LINQ'在很多情況下是'不可讀'的。查詢越複雜,我們可以感受到的越難以讀懂,也許這是因爲它的「簡潔」。 –