简体   繁体   中英

How can I convert a list<> to a multi-dimensional array?

I have the following method signature:

public void MyFunction(Object[,] obj)

I create this object:

List<List<Object>> obj = new List<List<Object>>;

Is there an easy way I can convert this to an Object[,] ?


UPDATE:

The fact is I like to use List s because I can easily add a new item. Is there a way I can declare my List<> object to fit this need? I know the number of columns in my Object[,] but not the number of rows.

No. In fact, these aren't necessarily compatible arrays.

[,] defines a multidimensional array. List<List<T>> would correspond more to a jagged array ( object[][] ).

The problem is that, with your original object, each List<object> contained in the list of lists can have a different number of objects. You would need to make a multidimensional array of the largest length of the internal list, and pad with null values or something along those lines to make it match.

You're not going to get a very simple solution for this (ie a few lines). LINQ/the Enumerable class isn't going to help you in this case (though it could if you wanted a jagged array, ie Object[][] ). Plain nested iteration is probably the best solution in this case.

public static T[,] To2dArray(this List<List<T>> list)
{
    if (list.Count == 0 || list[0].Count == 0)
        throw new ArgumentException("The list must have non-zero dimensions.");

    var result = new T[list.Count, list[0].Count];
    for(int i = 0; i < list.Count; i++)
    {
        for(int j = 0; j < list[i].Count; j++)
        {
            if (list[i].Count != list[0].Count)
                throw new InvalidOperationException("The list cannot contain elements (lists) of different sizes.");
            result[i, j] = list[i][j];
        }
    }

    return result;
}

I've included a bit of error handling in the function just because it might cause some confusing errors if you used it on a non-square nested list.

This method of course assumes that each List<T> contained as an element of the parent List is of the same length. (Otherwise you really need to be using a jagged array.)

Here is a solution using Linq's Aggregate extension.

Note that the below does not check, nor is concerned if it gets a jagged sub list, it uses the max size of all the sublists and fills in according to the current list. If that is a concern one could add a check to the if to check for the same count amongst all the sub lists.

public static T[,] To2DArray<T>(this List<List<T>> lst)
{

    if ((lst == null) || (lst.Any (subList => subList.Any() == false)))
        throw new ArgumentException("Input list is not properly formatted with valid data");

    int index = 0;
    int subindex;

    return 

       lst.Aggregate(new T[lst.Count(), lst.Max (sub => sub.Count())],
                     (array, subList) => 
                        { 
                           subindex = 0;
                           subList.ForEach(itm => array[index, subindex++] = itm);
                           ++index;
                           return array;
                         } );
}

Test / Usage

var lst = new List<List<string>>() { new List<string>() { "Alpha", "Beta", "Gamma" },
                                     new List<string>() { "One", "Two", "Three" },
                                     new List<string>() { "A" }
                                 };
var newArray = lst.To2DArray();

Result:

在此处输入图像描述

To be blunt, the answer is no, not easily.

Perhaps you would like to edit your question to give us more background about why these declarations are needed and we can help you with your root problem?


Re your update:

I assume you cannot change the function you need to pass this into.

I don't see why you cannot just use an object[,] to begin with. This is my recommendation.

I doubt this will help you in your situation, but it might make some of the array working easier on you to start with. Do you know about the .ToArray() method on a List ?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM