【问题标题】:Combining two double[] arrays into double[,]将两个 double[] 数组组合成 double[,]
【发布时间】:2013-09-11 07:42:42
【问题描述】:

我经常需要将两个数组组合成一个矩阵(相同的长度和类型)。我想知道是否有比以下更优雅的 linq 方式:

var result = new double[dt.Count, 2];

for (int i = 0; i < dt.Count; i++)
{
    result[i, 0] = dts[i];
    result[i, 1] = dt[i];
}

我试过了

var result = dts.zip(dt, (a,b) => new{a,b})

和:

var result = dts.Concat(dt).ToArray()

但我想做的事也不做……

【问题讨论】:

  • 恐怕您无法将二维数组作为标准 LINQ 输出。您可以创建自己的扩展方法(如this one),但它不会比标准的for loopw 更有效)
  • 此外,您可以编写自己的扩展方法(根据您的喜好实现,我想知道 LINQ 是否是数学相关内容的好选择...)
  • @BassamAlugili:我看了这个问题,但我认为它不一样,因为我在下面查看了 sourabh 的相同答案,但这并没有达到我想要的效果。被勾选为正确的答案也将它们堆叠在一起......
  • @nik 重复链接中的信息解决了同样的问题不用担心这个;这只是给有同样问题的人的信息。

标签: c# linq


【解决方案1】:

框架中没有任何内容,但这是一个通用解决方案(适用于 2 个或更多数组):

public static class ArrayConvert
{
    public static T[,] To2DArray<T>(params T[][] arrays)
    {
        if (arrays == null) throw new ArgumentNullException("arrays");
        foreach (var a in arrays)
        {
            if (a == null) throw new ArgumentException("can not contain null arrays");
            if (a.Length != arrays[0].Length) throw new ArgumentException("input arrays should have the same length");
        }

        var height = arrays.Length;
        var width = arrays[0].Length;

        var result = new T[width, height];

        for (int i = 0; i < height; i++) 
            for (int j = 0; j < width; j++)
        {
            result[i, j] = arrays[i][j];
        }

        return result;
    }
}

然后可以按如下方式使用:

var convertedArray = ArrayConvert.To2DArray(new[]{1,2,3}, new[]{4,5,6}, new[]{7,8,9});

【讨论】:

  • var height = arrays.Length; var 宽度 = 数组 [0].Length; var 结果 = 新 T[高度,宽度]; for (int i = 0; i
【解决方案2】:

好的,那就用这个

class Program {
    static void Main(string[] args) {

        double[,] x = { { 1, 2, 3 }, { 4, 5, 6 } };
        double[,] y = { { 7, 8, 9 }, { 10, 11, 12 } };

        var xy = new StitchMatrix<int>(x, y);

        Console.WriteLine("0,0=" + xy[0, 0]); // 1
        Console.WriteLine("1,1=" + xy[1, 1]); // 5
        Console.WriteLine("1,2=" + xy[1, 2]); // 6
        Console.WriteLine("2,2=" + xy[2, 2]); // 9
        Console.WriteLine("3,2=" + xy[3, 2]); // 12
    }
}

class StitchMatrix<T> {
    private T[][,] _matrices;
    private double[] _lengths;

    public StitchMatrix(params T[][,] matrices) {
        // TODO: check they're all same size          
        _matrices = matrices;

        // call uperbound once for speed
        _lengths = _matrices.Select(m => m.GetUpperBound(0)).ToArray();
    }

    public T this[double x, double y] {
        get {
            // find the right matrix
            double iMatrix = 0;
            while (_lengths[iMatrix] < x) {
                x -= (_lengths[iMatrix] + 1);
                iMatrix++;
            }
            // return value at cell
            return _matrices[iMatrix][x, y];
        }
    }
}

【讨论】:

  • 在 OP 的问题中,输入数组不是二维的。问题是如何从 2 个相同大小的一维数组优雅地创建一个二维数组。
  • OP 有 2 个 double[],而不是 2 个 double[,]
【解决方案3】:

这是另一种解决方案。我为 LINQ 处理“准备”输入。不确定这是否优雅,但它是 LINQ:

        // the input
        double[] dts = { 1, 2, 3, 4, 5 };
        double[] dt = { 10, 20, 30, 40, 50 };

        // list of lists, for iterating the input with LINQ
        double[][] combined = { dts, dt };

        var indexes = Enumerable.Range(0, dt.Length);
        var subIndexes = Enumerable.Range(0, 2);

        // the output
        var result = new double[dt.Length, 2];


        var sss = from i in indexes
                  from j in subIndexes
                  select result[i, j] = combined[j][i];

        // just to activate the LINQ iterator 
        sss.ToList();

【讨论】:

    【解决方案4】:

    我建议不要直接在 LINQ 中执行此操作。您可以编写一个通用方法来为您执行此操作,例如:

        public static T[,] To2DArray<T>(this T[][] arr)
        {
            if (arr.Length == 0)
            {
                return new T[,]{};
            }
    
            int standardLength = arr[0].Length;
    
            foreach (var x in arr)
            {
                if (x.Length != standardLength)
                {
                    throw new ArgumentException("Arrays must have all the same length");
                }
            }
    
            T[,] solution = new T[arr.Length, standardLength];
            for (int i = 0; i < arr.Length; i++)
            {
                for (int j = 0; j < standardLength; j++)
                {
                    solution[i, j] = arr[i][j];
                }
            }
            return solution;
        }
    

    【讨论】:

      【解决方案5】:

      我知道这不是问题,但最优雅的答案是使用 f#:

      let combinearrays (arr1:array<'a>) (arr2:array<'a>) = 
          let rws = arr1|> Array.length
          Array2D.init rws 2 (fun i j -> match j with |0 -> arr1.[i] |1 -> arr2.[i]) 
      

      来自约翰see here

      【讨论】:

        【解决方案6】:

        这是我为自己使用而开发的将两个一维数组转换为一个二维数组的解决方案。

        (from a1 in array1.Select((n,index)=>new{Index=index,c1=n}).ToList() 
         join a2 in array2.Select((n,index)=>new {Index=index,c2=n}).ToList() on a1.Index equals a2.Index 
        select new  {c1,c2}
        ).ToArray()
        

        【讨论】:

          猜你喜欢
          • 2020-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-12-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多