【问题标题】:Converting a bidimensional array of floats to bools将浮点数的二维数组转换为布尔值
【发布时间】:2016-12-08 04:43:20
【问题描述】:

假设我有一个二维浮点数组

float [,] myfloats = new float[10, 10]
FillWithValues(myfloats);

如何使用随机评估方法将此二维浮点数组转换为二维布尔数组?

我希望是这样的:

bool[,] mybools;
mybools = myfloats.Select(myfloat => Evaluate(myfloat));

但这不起作用...

【问题讨论】:

  • 我希望有一个映射方法,让它更优雅。但如果这是你的答案,请发布代码:) 我不确定如何循环遍历二维数组..
  • 在此处查看@Jon Skeet 的回答,这应该有助于理解为什么缺少“更优雅”:stackoverflow.com/questions/275073/…

标签: c#


【解决方案1】:

不幸的是,多维数组与 LINQ 不兼容并且有点难以处理。我认为没有办法绕过这个双循环解决方案:

bool[,] mybools = new bool[myfloats.GetLength(0), myfloats.GetLength(1)];
for (int x = 0; x<myfloats.GetLength(0); x++)
    for(int y=0; y<myfloats.GetLength(1); y++)
        mybools[x,y] = Evaluate(myfloats[x,y]);

Array.GetLength(Int32) 为您提供特定维度中数组的大小。

【讨论】:

    【解决方案2】:

    这不是特别有效,但有两种扩展方法可以做到这一点:

    var floats = new float[3, 3] {
       { 1f, 2f, 3f },
       { 4f, 5f, 6f },
       { 7f, 8f, 9f }
    };
    
    Func<float, bool> floatToBool = f => f > 5f;
    
    var bools =
       floats
       .ToJaggedArray()
       .Select(array => array.Select(floatToBool).ToArray())
       .ToArray()
       .To2DArray();
    

    请注意,您必须将其操作回“数组数组”才能返回二维数组。

    如果我们转换为 enumerable of enumerables 而不是锯齿状数组,效果会更好。然后它可能看起来像这样:

    var bools =
       floats
       .ToEnumerableOfEnumerables()
       .Select(array => array.Select(floatToBool))
       .To2DArray();
    

    第一部分的两个扩展方法是这样的:

    [Pure, NotNull]
    public static T[][] ToJaggedArray<T>([NotNull] this T[,] p2DArray) {
       var height = p2DArray.GetLength(0);
       var width = p2DArray.GetLength(1);
    
       var result = new T[height][];
    
       for (var row = 0; row < height; row++) {
          result[row] = new T[width];
          for (var col = 0; col < width; col++)
             result[row][col] = p2DArray[row, col];
       }
    
       return result;
    }
    
    [Pure, NotNull]
    public static T[,] To2DArray<T>([NotNull] this T[][] pJaggedArray) {
       if (!pJaggedArray.Any() || !pJaggedArray[0].Any())
          return new T[0, 0];
    
       var height = pJaggedArray.Length;
       var width = pJaggedArray[0].Length;
    
       var result = new T[height, width];
       for (var r = 0; r < height; r++) {
          var subArray = pJaggedArray[r];
          if (subArray == null || subArray.Length != width)
             throw new InvalidOperationException("Jagged array was not rectangular.");
    
          for (var c = 0; c < width; c++)
             result[r, c] = subArray[c];
       }
    
       return result;
    }
    

    第二部分是这样的:

    [Pure, NotNull]
    public static IEnumerable<IEnumerable<T>> ToEnumerableOfEnumerables<T>(
       [NotNull] this T[,] p2DArray
    ) {
       var height = p2DArray.GetLength(0);
    
       for (var row = 0; row < height; row++)
          yield return p2DArray.GetPartialEnumerable(row);
    }
    
    [Pure, NotNull]
    public static IEnumerable<T> GetPartialEnumerable<T>(
       [NotNull] this T[,] p2DArray,
       int pRow
    ) {
       var width = p2DArray.GetLength(1);
    
       for (var col = 0; col < width; col++)
          yield return p2DArray[pRow, col];
    }
    
    [Pure, NotNull]
    public static T[,] To2DArray<T>(
       [NotNull] this IEnumerable<IEnumerable<T>> pJaggedArray
    ) {
       if (!pJaggedArray.Any() || !pJaggedArray.First().Any())
          return new T[0, 0];
    
       var height = pJaggedArray.Count();
       var width = pJaggedArray.First().Count();
    
       var result = new T[height, width];
       var r = 0;
       foreach (var subArray in pJaggedArray) {
          if (subArray == null || subArray.Count() != width)
             throw new InvalidOperationException("Jagged array was not rectangular.");
    
          var c = 0;
          foreach (var item in subArray)
             result[r, c++] = item;
    
          r += 1;
       }
    
       return result;
    }
    

    【讨论】:

    • 呸! :) 你想多了:Enumerable.Range(0, n).Select(x =&gt; Enumerable.Range(0, m).Select(y =&gt; (stuff[x, y] = (x * y)) &gt; 10).ToArray()).ToArray(); - 你既可以返回新数组,也可以通过这种方式为现有数组赋值(可能建议 ToList()/ToArray() 实际执行可枚举)。当然返回类型将是 [n][m],而不是 [n,m],因为在这种情况下不应该使用 LINQ ;)
    猜你喜欢
    • 2023-04-03
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-09
    • 2014-01-22
    • 2014-07-29
    相关资源
    最近更新 更多