将两个double []数组合并为double [,]

时间:2013-09-11 07:42:42

标签: c# linq

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

但是我想做什么......

6 个答案:

答案 0 :(得分:2)

框架中没有任何内容,但如果这是您需要做的事情,您可以轻松地为此定义自己的类似linq的扩展方法:

public static class Ex
{
    public static T[,] To2DArray<T>(this T[] left, T[] right)
    {
        if (left == null) throw new ArgumentNullException("left");
        if (right == null) throw new ArgumentNullException("right");
        if (left.Length != right.Length) throw new ArgumentException("input arrays should have the same length");

        var result = new T[left.Length, 2];

        for (int i = 0; i < left.Length; i++)
        {
            result[i, 0] = right[i];
            result[i, 1] = left[i];
        }

        return result;
    }
}

使用方法如下:

var combined = left.To2DArray(right);
编辑:重新审视这个答案,我意识到有一个更通用的解决方案。像这样:

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});

答案 1 :(得分: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];
        }
    }
}

答案 2 :(得分: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();

答案 3 :(得分: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;
    }

答案 4 :(得分: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]) 

来自John see here

答案 5 :(得分:0)

这是解决方案在一个2D阵列中转换两个1d阵列,我自己开发它。

(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()