Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert an object array of object arrays to a two dimensional array of object

Tags:

arrays

c#

linq

I have a third party library returning an object array of object arrays that I can stuff into an object[]:

object[] arr = myLib.GetData(...);

The resulting array consists of object[] entries, so you can think of the return value as some kind of recordset with the outer array representing the rows and the inner arrays containing the field values where some fields might not be filled (a jagged array). To access the individual fields I have to cast like:

int i = (int) ((object[])arr[row])[col];//access a field containing an int

Now as I'm lazy I want to access the elements like this:

int i = (int) arr[row][col];

To do this I use the following Linq query:

object[] result = myLib.GetData(...);
object[][] arr = result.Select(o => (object[])o ).ToArray();

I tried using a simple cast like object[][] arr = (object[][])result; but that fails with a runtime error.

Now, my questions:

  • Is there a simpler way of doing this? I have the feeling that some nifty cast should do the trick?
  • Also I am worried about performance as I have to reshape a lot of data just to save me some casting, so I wonder if this is really worth it?

EDIT: Thank you all for the speedy answers.
@James: I like your answer wrapping up the culprit in a new class, but the drawback is that I always have to do the Linq wrapping when taking in the source array and the indexer needs both row and col values int i = (int) arr[row, col]; (I need to get a complete row as well like object[] row = arr[row];, sorry didn't post that in the beginning).
@Sergiu Mindras: Like James, i feel the extension method a bit dangerous as it would apply to all object[] variables.
@Nair: I chose your answer for my implementation, as it does not need using the Linq wrapper and I can access both individual fields using int i = (int) arr[row][col]; or an entire row using object[] row = arr[row];
@quetzalcoatl and @Abe Heidebrecht: Thanks for the hints on Cast<>().

Conclusion: I wish I could choose both James' and Nair's answer, but as I stated above, Nair's solution gives me (I think) the best flexibility and performance. I added a function that will 'flatten' the internal array using the above Linq statement because I have other functions that need to be fed with such a structure.

Here is how I (roughly) implemented it (taken from Nair's solution:

public class CustomArray { private object[] data; public CustomArray(object[] arr) { data = arr; }

        //get a row of the data
        public object[] this[int index]
        { get { return (object[]) data[index]; } }

        //get a field from the data
        public object this[int row, int col]
        { get { return ((object[])data[row])[col]; } }

        //get the array as 'real' 2D - Array
        public object[][] Data2D()
        {//this could be cached in case it is accessed more than once
            return data.Select(o => (object[])o ).ToArray()
        }

        static void Main()
        {
            var ca = new CustomArray(new object[] { 
                      new object[] {1,2,3,4,5 },
                      new object[] {1,2,3,4 },
                      new object[] {1,2 } });
            var row = ca[1]; //gets a full row
            int i = (int) ca[2,1]; //gets a field
            int j = (int) ca[2][1]; //gets me the same field
            object[][] arr = ca.Data2D(); //gets the complete array as 2D-array
        }

    }

So - again - thank you all! It always is a real pleasure and enlightenment to use this site.

like image 602
AstaDev Avatar asked Jun 26 '13 14:06

AstaDev


People also ask

How do I turn an array into a 2D array?

Use reshape() Function to Transform 1d Array to 2d Array The number of components within every dimension defines the form of the array. We may add or delete parameters or adjust the number of items within every dimension by using reshaping.

How do you convert a one-dimensional array to a two-dimensional array in C?

So the total number of elements of 1D array = (​ m * n ​ ) elements. Call the function​ ​ input_array​ to store elements in 1D array. Call the function ​ print_array​ to print the elements of 1D array. Call the function ​ array_to_matrix​ to convert 1D array to 2D array.

Can you make a 2D array of objects in Java?

Java Two Dimensional Array of Objects We can declare a 2D array of objects in the following manner: ClassName[][] ArrayName; This syntax declares a two-dimensional array having the name ArrayName that can store the objects of class ClassName in tabular form.

How do you convert a single array of objects into an object?

assign() method to convert an array of objects to a single object. This merges each object into a single resultant object. The Object. assign() method also merges the properties of one or more objects into a single object.


2 Answers

There are few similar answer posted which does something similar. This differ only if you want to acess like

int i = (int) arr[row][col]; 

To demonstrate the idea

   public class CustomArray
        {
            private object[] _arr;
            public CustomArray(object[] arr)
            {
                _arr = arr;
            }

            public object[] this[int index]
            {
                get
                {
                    // This indexer is very simple, and just returns or sets 
                    // the corresponding element from the internal array. 
                    return (object[]) _arr[index];
                }
            }
            static void Main()
            {
                var c = new CustomArray(new object[] { new object[] {1,2,3,4,5 }, new object[] {1,2,3,4 }, new object[] {1,2 } });
                var a =(int) c[1][2]; //here a will be 4 as you asked.
            }

        }
like image 149
Sreejith Nair Avatar answered Oct 06 '22 04:10

Sreejith Nair


(1) This probably could be done in short and easy form with dynamic keyword, but you'll use compile-time checking. But considering that you use object[], that's a small price:

dynamic results = obj.GetData();
object something = results[0][1];

I've not checked it with a compiler though.

(2) instead of Select(o => (type)o) there's a dedicated Cast<> function:

var tmp = items.Select(o => (object[])o).ToArray();
var tmp = items.Cast<object[]>().ToArray();

They are almost the same. I'd guess that Cast is a bit faster, but again, I've not checked that.

(3) Yes, reshaping in that way will affect the performance somewhat, depending mostly on the amount of items. The impact will be the larger the more elements you have. That's mostly related to .ToArray as it will enumerate all the items and it will make an additional array. Consider this:

var results = ((object[])obj.GetData()).Cast<object[]>();

The 'results' here are of type IEnumerable<object[]> and the difference is that it will be enumerated lazily, so the extra iteration over all elements is gone, the temporary extra array is gone, and also the overhead is minimal - similar to manual casting of every element, which you'd do anyways.. But - you lose the ability to index over the topmost array. You can loop/foreach over it, but you cannot index/[123] it.

EDIT:

The James's wrapper way is probably the best in terms of overall performance. I like it the most for readability, but that's personal opinion. Others may like LINQ more. But, I like it. I'd suggest James' wrapper.

like image 30
quetzalcoatl Avatar answered Oct 06 '22 05:10

quetzalcoatl