4

我经常有两个数组需要组合成一个矩阵(相同的长度和类型)。我想知道是否有一种比以下更优雅的 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()

但也没有做我想做的事......

4

6 回答 6

3

框架中没有任何内容,但这是一个通用解决方案(适用于 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});
于 2013-09-11T07:55:30.377 回答
1

好的,然后使用这个

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];
        }
    }
}
于 2013-09-11T07:51:57.420 回答
1

这是另一个解决方案。我为 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();
于 2013-09-11T10:46:31.013 回答
0

我建议不要直接在 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;
    }
于 2013-09-11T07:56:40.197 回答
0

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

(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()
于 2015-05-01T20:14:41.400 回答
0

我知道这不是问题,但最优雅的答案是使用 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]) 

从约翰看这里

于 2013-10-09T10:47:31.653 回答