views:

95

answers:

3

Say I have a

List<double[]> x = new List<double[]>();
double[] item = new double[] {1.0,2.0,3.0};
x.add(item);
etc...

Is there a faster/cleaner way to get this into a double[,] then looping it:

double[,] arr = new double[x.Count,3];          
for (row = 0; row < x.Count; row++)
{
    for (col = 0; col < 3; col++)
        arr[row,col] = x[row][col];
}

Thanks.

+3  A: 

No, there isn't.

Multi-dimensional arrays are strange beasts and are not widely accepted or used in the BCL.

They're also slow and should be avoided where possible.

SLaks
Can you provide some clarification on the performance issue?
Jon Benedicto
I hadn't heard of performance issues either. Maybe you are thinking of jagged arrays instead of multi-dimensional ones? Also, VB is happy to work with multi-dimensional arrays. VB is the lowest common denominator as far as I'm concerned.
Scott P
IIRC, multi-dimensional array access is done through system calls, causing the slowness, unlike single-dimensional array access which is done directly with CIL instructions.
Qwertie
@Scott: On the contrary. Jagged arrays are fully normal; multi-dimensional ones are slow. Qwertie is correct. I'm talking about BCL methods, not language support. Also, VB is not the lowest common denominator - exception filters, interface maps, etc
SLaks
Interesting. Thanks for the explanation. Have you any idea how much of a difference we are talking about? I analyze a lot of 3D data and routinely use multi-dimensional arrays.
Scott P
@Scott: No idea. If you're concerned, run a profiler or do a simple test.
SLaks
+2  A: 

Because I felt like it, I solved this using LINQ, however, it's hardly any cleaner. In fact, I'd argue it's less clear, but it'd danm neat :)

// Input
List<double[]> a = new List<double[]>() { 
    new double[]{ 1.0, 2.0, 3.0 },
    new double[]{ 4.0, 5.0, 6.0 },
    new double[]{ 7.0, 8.0, 9.0 }
};

// Output
var b = a.Select((item, index) => new 
            { 
                Items = item.Select((inner, inIndex) => new { Inner = inner, Y = inIndex }),
                X = index 
            })
            .SelectMany(item => item.Items, (i, inner) => new { Value = inner.Inner, X = i.X, Y = inner.Y })
            .Aggregate(new double[a.Count, a.Max(aa => aa.Length)], (acc, item) => { acc[item.X, item.Y] = item.Value; return acc; })

Note: This also works for arbitrarily sized inner double[] arrays, but there will be empty spots.

So yes, there's another way of doing it, but it's not a better way :)

Aren
+1 for taking the time to investigate. Going through the process only to decide this approach is not so practical is still a useful bit of knowledge IMHO.
Rob Levine
A: 

There is always the var_export function?

Ekampp
No, there isn't.
SLaks
Wow.. Good response. That is very, both productive and helpful!
Ekampp