2013-03-13 24 views
2

我有一個二維數組(double[ , ]),我想知道最小值是多少。我試過Linq.Select.Min,但由於我的數組通常包含NaN值,因此minvalue總是NaN從NaNs多維數組中找出最小值

所以,我需要一些方法來找到「跳過」NaN的最小值。

任何幫助非常感謝!

回答

4

今天是擴展方法的一天!使用它可以在你所有的double[,]上有一個通用的Min()功能!

繼承人一些泛型[,]擴展。請注意,這將只可用於實現IComparable

這一個類型忽略了什麼:

public static T Min<T>(this T[,] arr) where T : IComparable 
{ 
    bool minSet = false; 
    T min = default(T); 
    for (int i = 0; i < arr.GetLength(0); i++) 
     for (int j = 0; j < arr.GetLength(1); j++) 
      if (!minSet) 
      { 
       minSet = true; 
       min = arr[i, j]; 
      } 
      else if (arr[i, j].CompareTo(min) < 0) 
       min = arr[i, j]; 
    return min; 
} 

這一個將讓您指定的值忽略,而在特殊情況下陣列只包含忽略值,它會返回忽略的值。

public static T Min<T>(this T[,] arr, T ignore) where T : IComparable 
{ 
    bool minSet = false; 
    T min = default(T);    
    for (int i = 0; i < arr.GetLength(0); i++) 
     for (int j = 0; j < arr.GetLength(1); j++) 
      if (arr[i, j].CompareTo(ignore) != 0) 
       if (!minSet) 
       { 
        minSet = true; 
        min = arr[i, j]; 
       } 
       else if (arr[i, j].CompareTo(min) < 0) 
        min = arr[i, j]; 
    return (minSet) ? min : ignore; 
} 

以下代碼的輸出是

的NaN
-10

double[,] d = new double[5, 5] 
{ 
    { 0, 1, 2, 3, 4 }, 
    { 5, 6, 7, 8, 9 }, 
    { 10, 11, -10, 12, 13 }, 
    { 14, 15, 16, 17, 18 }, 
    { 19, double.NaN, 21, 22, 23 } 
}; 
Console.WriteLine(d.Min()); 
Console.WriteLine(d.Min(double.NaN)); 
+0

有趣......您如何看待這種基準測試與更高級別的LINQ方法相比呢? – heltonbiker 2013-03-13 19:54:28

+0

它可能會稍微更快,除非有一些幕後優化,我不知道在LINQ庫(在這種情況下,我懷疑)。在LINQ版本中,您還可以使用Select創建N個IEnumerables,其中N是數組第一維的長度。 – FlyingStreudel 2013-03-13 19:57:35

+0

我測試了這個,它工作。我很容易接受這一點,除了別人出現了一個非常聰明的LINQ表達式,也可以... – heltonbiker 2013-03-13 20:00:24

3

試試這個:

var minvalue = System.Linq.Enumerable.Range(0, 4) 
    .Where(i => !Double.IsNa(myarray[i,1])) 
    .Select(i => myarray[i, 1]).Min(); 

更新:

double[,] myarray = new double[4,4]; 

    var rows = myarray.GetLength(0); 
    var cols = myarray.GetLength(1); 

    Enumerable.Range(0, rows * cols) 
    .Where(i => !Double.IsNaN(myarray[i/rows, i%rows])) 
    .Select(i => myarray[i/rows, i%rows]) 
    .Min(); 

票友使用.Range的()無疑是可能的,我將現在的研究。

+0

我編輯的問題。 'Range(0,4)'不應該在那裏(它是複製粘貼的),我不確定提供的代碼在兩個維度上都起作用。你可以編輯你的答案考慮一個通用的二維數組?我會很高興接受它。 – heltonbiker 2013-03-13 19:51:40

+0

您正在尋找兩個維度的所有單元格中的最小值? – 2013-03-13 19:52:49

+0

是的。假設陣列是一個地形的數字高程模型(它是,有點),在網格中有一些無效值。我想找到地形的「最低」高程(不考慮它的位置)。 – heltonbiker 2013-03-13 19:56:52

3
public static double MinIsNumber(double[,] array) 
{ 
    return array.Cast<double>() 
     .Where(n => !double.IsNaN(n)) 
     .Min(); 
} 
相關問題