views:

105

answers:

3

Is there a more performant way to concatenate 2-d arrays than this?

  static void Main(string[] args)
    {

        int[][] array1 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } } ;             

        int[][] array2 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } };

        int[][] array3 = Concat(array1, array2);

    }

    private static int[][] Concat(int[][] array1, int[][] array2)
    {
        int array1Length = array1.Length;
        int array2Length = array2.Length;

        int[][] result = new int[array1Length + array2Length][];
        int i = 0;
        for (; i < array1Length; i++)
            result[i] = array1[i];

        for (; i < array2Length + array1Length; i++)
            result[i] = array2[i - array1Length];

        return result;    



    }

Edit: I would like to know if that's a good practice of deep concat of 2d array

        private static int[][] DeepConcat(int[][] array1, int[][] array2)
    {
        int array1Length = array1.Length;
        int array2Length = array2.Length;

        int[][] result = new int[array1Length + array2Length][];
        int i = 0;
        for (; i < array1Length; i++)
        {
            result[i] = new int[array1[i].Length];
            for (int j = 0; j < array1[i].Length; j++)
            {
                result[i][j] = array1[i][j];
            }
        }
        for (; i < array2Length + array1Length; i++)
        {
            result[i] = new int[array2[i - array1Length].Length];
            for (int j = 0; j < array2[i - array1Length].Length; j++)
            {
                result[i][j] = array2[i - array1Length][j];
            }

        }
        return result;

    }
+3  A: 

You could use a linked list of int[] instead so you don't need to re-allocate any new memory.

See LinkedList<T>, or if it doesn't perform exactly as you want for concat you can make your own easily.

Brian R. Bondy
A: 

I doubt this will be alot faster, but perhaps it's a bit more readable:

int[][] array3 = new int[array1.Length + array2.Length][];

Array.Copy(array1, 0, array3, 0, array1.Length);
Array.Copy(array2, 0, array3, array1.Length, array2.Length);

Edit: in a critical part of your application, it might be worth it - it's a shame Buffer.BlockCopy doesn't work on "nested" int[] arrays :(

deltreme
+2  A: 

Your issue can be simplified to the same question as this one.

So my solution for you would be:

    private static int[][] Concat(int[][] array1, int[][] array2)
    {
        int[][] result = new int[array1.Length + array1.Length][];

        array1.CopyTo(result, 0);
        array2.CopyTo(result, array1.Length);

        return result;
    }

*I can't find the comment link below the original question. So editing my own post.

Mustafa, I would like to ask you: Do you intend to copy arrays in new memory? Because your original concat method only copy array references. So after creating array3 (using original concat()), if you change anything in array1 and array2, then array3 will change as well. I hope you are aware of that. If you intended to have separate memory block for array3, then only use my method (or deltreme's method).

bits
no .. the copyto also copies references .. check this outint[][] array1 = { new int[] { 1, 2, 3 }, new int[] { 4, 5, 6 }, new int[] { 7, 8, 9 } } ; int[][] array3 = new int[array1.Length][]; array1.CopyTo(array3,0); array1[0][0] = 1000; if (array1[0][0] == array3[0][0]) Console.WriteLine("Gotcha");
Mustafa A. Jabbar
Oh wow. Thanks Mustafa, for letting me know about this. I learned something as well.Atleast in that case, this solution perfectly suits your requirement. Because you didn't care about copying references.
bits