2013-03-13 23 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(); 
} 
相关问题