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[,]
?
有没有一种简单的方法可以将它转换为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.
事实是我喜欢使用列表,因为我可以轻松添加新项目。有没有办法可以声明我的List <>对象以满足这种需要?我知道对象[,]中的列数,但不知道行数。
4 个解决方案
#1
11
No. In fact, these aren't necessarily compatible arrays.
实际上,这些不一定是兼容的阵列。
[,]
defines a multidimensional array. List<List<T>>
would correspond more to a jagged array ( object[][]
).
[,]定义了一个多维数组。 List
>更多地对应于锯齿状数组(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.
问题在于,对于原始对象,列表列表中包含的每个List
#2
6
You're not going to get a very simple solution for this (i.e. 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, i.e. Object[][]
). Plain nested iteration is probably the best solution in this case.
你不会为此得到一个非常简单的解决方案(即几行)。在这种情况下,LINQ / Enumerable类不会帮助你(尽管如果你想要一个锯齿状数组,也就是Object [] [])。在这种情况下,纯嵌套迭代可能是最好的解决方案。
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.)
当然,该方法假定包含为父List的元素的每个List
#3
2
Here is a solution using Linq's Aggregate
extension.
这是使用Linq的Aggregate扩展的解决方案。
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.
请注意,下面不检查,也不关心它是否有一个锯齿状子列表,它使用所有子列表的最大大小并根据当前列表填写。如果这是一个问题,可以添加检查if以检查所有子列表中的相同计数。
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:
#4
-2
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
?
我怀疑这会对你的情况有所帮助,但它可能会使你的一些阵列更容易开始。你知道List上的.ToArray()方法吗?
#1
11
No. In fact, these aren't necessarily compatible arrays.
实际上,这些不一定是兼容的阵列。
[,]
defines a multidimensional array. List<List<T>>
would correspond more to a jagged array ( object[][]
).
[,]定义了一个多维数组。 List
>更多地对应于锯齿状数组(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.
问题在于,对于原始对象,列表列表中包含的每个List
#2
6
You're not going to get a very simple solution for this (i.e. 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, i.e. Object[][]
). Plain nested iteration is probably the best solution in this case.
你不会为此得到一个非常简单的解决方案(即几行)。在这种情况下,LINQ / Enumerable类不会帮助你(尽管如果你想要一个锯齿状数组,也就是Object [] [])。在这种情况下,纯嵌套迭代可能是最好的解决方案。
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.)
当然,该方法假定包含为父List的元素的每个List
#3
2
Here is a solution using Linq's Aggregate
extension.
这是使用Linq的Aggregate扩展的解决方案。
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.
请注意,下面不检查,也不关心它是否有一个锯齿状子列表,它使用所有子列表的最大大小并根据当前列表填写。如果这是一个问题,可以添加检查if以检查所有子列表中的相同计数。
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:
#4
-2
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
?
我怀疑这会对你的情况有所帮助,但它可能会使你的一些阵列更容易开始。你知道List上的.ToArray()方法吗?