Is there an one-liner (no looping) that converts List<double[]>
to double[,]
?
views:
112answers:
4
A:
If a 2 dim array is to be created from List of 1 dim array then looping is required, though it may not look like that at the call-site.
Hemal Pandya
2010-08-23 09:13:32
+4
A:
Converting to double[,]
can only be done by looping through the list and requires that all arrays contained in the list are of same size:
double[,] arr = new double[list.Count, list[0].Length];
for (int i = 0; i < list.Count; i++)
{
for (int j = 0; j < list[0].Length; j++)
{
arr[i, j] = list[i][j];
}
}
Of course, you can easily create a jagged double[][]
array of arrays by calling .ToArray()
:
double[] array = new double[] { 1.0, 2.0, 3.0 };
double[] array1 = new double[] { 4.0, 5.0, 6.0 };
List<double[]> list = new List<double[]>();
list.Add(array);
list.Add(array1);
double[][] jaggedArray = list.ToArray();
0xA3
2010-08-23 09:18:55
You also can add trailing zeroes if array isn't of the required size
abatishchev
2010-08-23 09:23:39
@abatishchev: Yes, good point. This would require an additional pass to find the maximum length entry in the list first so you can determine the array size needed.
0xA3
2010-08-23 09:25:21
Finding the longest array in the list first is better to use list[0].
Danny Chen
2010-08-23 09:39:49
@Danny: It's rather better to iterate one time more I think than trim all arrays longer than first
abatishchev
2010-08-23 09:42:15
@Danny: `new List<double[]>().Max(a => a.Lenght)`
abatishchev
2010-08-23 10:06:08
+2
A:
Well, you probably can't implement it without loops, but you can make the usage a one-liner :
double[,] array = list.To2DArray();
To2DArray
is an extension method implemented as follows:
public static class ExtensionMethods
{
public static T[,] To2DArray<T>(this IEnumerable<IEnumerable<T>> source)
{
var jaggedArray = source.Select(r => r.ToArray()).ToArray();
int rows = jaggedArray.GetLength(0);
int columns = jaggedArray.Max(r => r.Length);
var array = new T[rows, columns];
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < jaggedArray[i].Length; j++)
{
array[i, j] = jaggedArray[i][j];
}
}
return array;
}
}
Note that it will only work in C# 4, since earlier versions don't support covariance. This variant should work in C# 3 but it is more specific:
public static T[,] To2DArray<T>(this IEnumerable<T[]> source)
{
var jaggedArray = source.ToArray();
// same code from here
}
Thomas Levesque
2010-08-23 09:24:44
You could use `int rows = source.Count(); int columns = source.Max(r => r.Count());` directly without creating a jagged array first.
0xA3
2010-08-23 09:57:21
Yes, but I need the jagged array afterwards to access the data (I could use the ElementAt method but it's wouldn't work for enumerables that can be enumerated only once)
Thomas Levesque
2010-08-23 11:14:42
A:
public static T[,] ToMultidimensional<T>(this T[][] arr, int maxSize)
{
T[,] md = (T[,])Array.CreateInstance(typeof(double), arr.Length, maxSize);
for (int i = 0; i < arr.Length; i++)
for (int j = 0; j < arr[i].Length; j++)
md[i, j] = arr[i][j];
return md;
}
var arr = new List<double[]>
{
new double[] { 1, 2, 3 },
new double[] { 4, 5 }
}
.ToArray();
var j = arr.ToMultidimensional(arr.Max(a => a.Length));
abatishchev
2010-08-23 10:36:32