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