C# 用于列出对象唯一组合的嵌套循环的动态数目
我有n个需要转换为对象数组列表的对象列表,每个数组包含原始列表中对象的唯一组合 例如:C# 用于列出对象唯一组合的嵌套循环的动态数目,c#,arrays,object,recursion,dynamic,C#,Arrays,Object,Recursion,Dynamic,我有n个需要转换为对象数组列表的对象列表,每个数组包含原始列表中对象的唯一组合 例如: myList[0] = new List<object>(){a, b, c, d}; myList[1] = new List<object>(){"0", "1", "2", "3", "4"}; myList[2] = new List<object>(){0, 1, 2}; myList[3] = new List<object>(){aClass, b
myList[0] = new List<object>(){a, b, c, d};
myList[1] = new List<object>(){"0", "1", "2", "3", "4"};
myList[2] = new List<object>(){0, 1, 2};
myList[3] = new List<object>(){aClass, bClass}
等等
必须保留变量的顺序(myList[0]中的列表必须是第一个,等等),因为这些对象数组是通过反射传递的参数:
Indicator temp = (Indicator) newIndicator.Invoke(this, newList[i]);
如果对象列表的数量是静态的,则可能如下所示:
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
List newList=newList();
对于(int i=0;i
我最近的一次尝试是创建一个索引列表,其中包含每个列表的当前索引,并适当地增加索引,但我的数学在扩展时似乎不起作用
private List<object[]> ToParametersList(List<List<object>> listOfLists)
{
int counter = 1;
foreach(List<object> list in listOfLists){ counter *= list.Count; }
List<object[]> returnList = new List<object[]>();
List<int> indicies = new List<int>();
int tempSplit = 0;
List<int> splits = new List<int>();
List<int> splitcounters = new List<int>();
for(int i = 0; i < listOfLists.Count; i++)
{
if(i == 0 && listOfLists[0].Count > 2)
{
splits.Add(counter / listOfLists[0].Count);
tempSplit = counter / listOfLists[0].Count;
} else if(i > 0 && listOfLists[i].Count > 2) {
splits.Add(tempSplit / listOfLists[i].Count);
tempSplit /= listOfLists[i].Count;
} else if(listOfLists[i].Count == 2)
{
splits.Add(1);
}
indicies.Add(0);
splitcounters.Add(1);
}
for(int i = 0; i < counter; i++)
{
object[] newObject = new object[listOfLists.Count];
for(int i2 = 0; i2 < listOfLists.Count; i2++)
{
if(i < splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else if(i >= splits[i2] * splitcounters[i2] && ((indicies[i2] < listOfLists[i2].Count && listOfLists[i2].Count > 2) || indicies[i2] < listOfLists[i2].Count - 1))
{
indicies[i2]++;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
else
{
indicies[i2] = 0;
splitcounters[i2]++;
newObject[i2] = listOfLists[i2][indicies[i2]];
}
}
returnList.Add(newObject);
}
return returnList;
}
私有列表TopParametersList(列表列表列表)
{
int计数器=1;
foreach(listOfLists中的列表){counter*=List.Count;}
List returnList=新列表();
列表标记=新列表();
int-tempslit=0;
列表拆分=新列表();
List splitcounters=新列表();
for(int i=0;i2)
{
splits.Add(计数器/列表[0].Count);
tempSplit=计数器/列表[0]。计数;
}else if(i>0&&listOfLists[i].Count>2){
splits.Add(tempslit/listOfLists[i].Count);
tempSplit/=listOfLists[i]。计数;
}else if(列表[i].Count==2)
{
拆分。添加(1);
}
添加(0);
添加(1);
}
对于(int i=0;i2)| |指示[i2]=splits[i2]*splitcounters[i2]&((指示[i2]2)| |指示[i2]
我也经历了这里的许多递归问题,但仍然难以理解如何将它们应用于这种特殊情况(我对递归比较陌生)
任何帮助都将不胜感激
编辑:在OP的帖子中,这是令人困惑的,并且提供的答案没有解释发生了什么。链接到的是对笛卡尔产品的总体概述,这并没有帮助我打破在我试图做的事情中正确理解这一点所需要的障碍 可以使用LINQ获得对象列表的笛卡尔积
List<object> arr1 = new List<object> { "a", "b", "c" };
List<object> arr2 = new List<object> { 3, 2, 4,5 };
List<object> arr3 = new List<object> { "0", "1", "2", "3", "4" };
var result = from x in arr1
from y in arr2
from z in arr3
select new { x = x, y = y,z=z };
List<object[]> newList = new List<object[]>();
foreach (var line in result)
{
newList.Add(new object[] { line.x, line.y, line.z });
}
foreach (var obj in newList)
{
foreach (var ele in obj)
{
Console.Write(ele.ToString() + " ");
}
Console.WriteLine();
}
Console.ReadKey();
List arr1=新列表{“a”、“b”、“c”};
List arr2=新列表{3,2,4,5};
List arr3=新列表{“0”、“1”、“2”、“3”、“4”};
var结果=从arr1中的x开始
从arr2的y开始
从arr3中的z开始
选择新的{x=x,y=y,z=z};
List newList=新列表();
foreach(结果中的var行)
{
添加(新对象[]{line.x,line.y,line.z});
}
foreach(新列表中的var obj)
{
foreach(obj中的var ele)
{
Console.Write(ele.ToString()+);
}
Console.WriteLine();
}
Console.ReadKey();
这将以您需要的方式为您提供一个对象列表
下面是一个运行示例
这里有一个解决方案,它接受许多在编译时未知的列表。
方法
CombinarLayofList
可以满足您的需要:
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = (from c1 in result from c2 in myList[i] select new List<object>(c1) {c2}).ToList();
}
return result;
}
静态列表组合rayofList(列表[]myList)
{
列表结果=myList[0]。选择(元素=>new List(){element})。ToList();
for(int i=1;i
请注意,如果列表数组中的任何列表为空,则需要定义所需的行为。要处理这种情况,您可能需要添加一个if语句来跳过该列表(如果这样做是适当的)
以更为详细的形式编写的完整示例更易于理解:
class Program
{
static void Main(string[] args)
{
List<object>[] myList = new List<object>[4];
AClass aClass = new AClass();
BClass bClass = new BClass();
myList[0] = new List<object>() { "a", "b", "c", "d" };
myList[1] = new List<object>() { "0", "1", "2", "3", "4" };
myList[2] = new List<object>() { 0, 1, 2 };
myList[3] = new List<object>() { aClass, bClass };
List<List<object>> result = CombineArrayOfLists(myList);
PrintList(result);
}
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = CombineCollections(result, myList[i]).ToList();
}
return result;
}
private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
{
return from c1 in collection1 from c2 in collection2 select new List<object>(c1) { c2 };
}
// A more verbose form of CombineCollections that may be easier to understand:
//private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
//{
// foreach (List<object> c1 in collection1)
// {
// foreach (object c2 in collection2)
// {
// List<object> l1 = new List<object>(c1) { c2 };
// yield return l1;
// }
// }
//}
private static void PrintList(List<List<object>> collection)
{
collection.ForEach(list =>
{
list.ForEach(element =>
{
Console.Write(element);
Console.Write(" ");
});
Console.WriteLine();
});
}
}
public class AClass
{ }
public class BClass
{ }
类程序
{
静态void Main(字符串[]参数)
{
列表[]myList=新列表[4];
AClass AClass=新的AClass();
b类b类=新的b类();
myList[0]=新列表(){“a”、“b”、“c”、“d”};
myList[1]=新列表(){“0”、“1”、“2”、“3”、“4”};
myList[2]=新列表(){0,1,2};
myList[3]=新列表(){aClass,bClass};
列表结果
class Program
{
static void Main(string[] args)
{
List<object>[] myList = new List<object>[4];
AClass aClass = new AClass();
BClass bClass = new BClass();
myList[0] = new List<object>() { "a", "b", "c", "d" };
myList[1] = new List<object>() { "0", "1", "2", "3", "4" };
myList[2] = new List<object>() { 0, 1, 2 };
myList[3] = new List<object>() { aClass, bClass };
List<List<object>> result = CombineArrayOfLists(myList);
PrintList(result);
}
static List<List<object>> CombineArrayOfLists(List<object>[] myList)
{
List<List<object>> result = myList[0].Select(element => new List<object>() { element }).ToList();
for (int i = 1; i < myList.Length; i++)
{
result = CombineCollections(result, myList[i]).ToList();
}
return result;
}
private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
{
return from c1 in collection1 from c2 in collection2 select new List<object>(c1) { c2 };
}
// A more verbose form of CombineCollections that may be easier to understand:
//private static IEnumerable<List<object>> CombineCollections(IEnumerable<List<object>> collection1, List<object> collection2)
//{
// foreach (List<object> c1 in collection1)
// {
// foreach (object c2 in collection2)
// {
// List<object> l1 = new List<object>(c1) { c2 };
// yield return l1;
// }
// }
//}
private static void PrintList(List<List<object>> collection)
{
collection.ForEach(list =>
{
list.ForEach(element =>
{
Console.Write(element);
Console.Write(" ");
});
Console.WriteLine();
});
}
}
public class AClass
{ }
public class BClass
{ }
List<object[]> newList = new List<object[]>();
for(int i = 0; i < myList[0].Count; i++)
{
for(int i2 = 0; i2 < myList[1].Count; i2++)
{
for(int i3 = 0; i3 < myList[2].Count; i3++)
{
for(int i4 = 0; i4 < myList[3].Count; i4++)
{
object[] temp = new object[]{myList[0][i], myList[1][i2], myList[2][i3], myList[3][i4]};
newList.Add(temp);
}
}
}
}
private static void Combine(List<List<object>> myList,List<object[]> newList,params int[] loopInd)
{
if (loopInd.Length <= myList.Count) // should not exceed number of loops.
{
int currentCount = myList[loopInd.Length - 1].Count;
while (loopInd[loopInd.Length - 1] < currentCount) // i<myList[0] , i2<myList[1] , i3<myList[2]
{
Combine(myList, newList, loopInd.Concat(new[] {0}).ToArray()); // Go for inner loop
loopInd[loopInd.Length - 1]++; // i++, i2++ , i3++ ...
}
}
else // no more loops.add the object[] into newList
{
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
}
}
List<List<object>> myList = new List<List<object>>();
myList.Add(new List<object>() { a, b, c, d });
myList.Add(new List<object>() { "0", "1", "2", "3", "4" });
myList.Add(new List<object>() { 0, 1, 2 });
myList.Add(new List<object>() {aClass, bClass});
List<object[]> newList = new List<object[]>();
Combine(myList, newList, 0);
// The newList is now what you want
int j = 0;
object[] temp = loopInd.Take(loopInd.Length - 1).Select(i => myList[j++][i]).ToArray();
newList.Add(temp);
int j = 0;
object[] temp = new object[loopInd.Length - 1];
for (int i = 0; i < loopInd.Length - 1; i++,j++)
{
temp[i] = myList[j][loopInd[i]];
}