C# 获取按名称分组的列表的所有组合
我有以下TestParam列表。。。这只是一个参数列表,用于确定如何运行查询。在以下情况下,将针对不同参数的所有组合执行预期结果。因此,列表列表中包含CustomerId 33以及列表中可用的每个产品IdC# 获取按名称分组的列表的所有组合,c#,.net,ienumerable,generic-list,C#,.net,Ienumerable,Generic List,我有以下TestParam列表。。。这只是一个参数列表,用于确定如何运行查询。在以下情况下,将针对不同参数的所有组合执行预期结果。因此,列表列表中包含CustomerId 33以及列表中可用的每个产品Id List<TestParam> testList = new List<TestParam>(); testList.Add(new TestParam() { Name = "CustomerId", Value = "33" });
List<TestParam> testList = new List<TestParam>();
testList.Add(new TestParam() { Name = "CustomerId", Value = "33" });
testList.Add(new TestParam() { Name = "ProductId", Value = "1" });
testList.Add(new TestParam() { Name = "ProductId", Value = "2" });
testList.Add(new TestParam() { Name = "ProductId", Value = "3" });
testList.Add(new TestParam() { Name = "ProductId", Value = "4" });
testList.Add(new TestParam() { Name = "ProductId", Value = "5" });
testList.Add(new TestParam() { Name = "ProductId", Value = "6" });
testList.Add(new TestParam() { Name = "ProductId", Value = "7" });
testList.Add(new TestParam() { Name = "ProductId", Value = "8" });
最终结果将是一个列表列表,其中包含CustomerId 33以及所有其他产品。如果我在TestParam列表中有不同的名称和值,将获得相同的结果(上面只是一个示例)
下面的代码,根据上面列表的组合以几个列表结束
// First get a list of distinct unique param collections...
List<string> distinctParameterNames = new List<string>();
testList.GroupBy(x => x.Name).ForEach(paramName => {
distinctParameterNames.Add(paramName.Key);
});
// Get counts
List<int> combinationList = new List<int>();
foreach (var x in distinctParameterNames) {
combinationList.Add(testList.Where(y=>y.Name == x).Count());
}
// Will contain 2 lists, one having all combinations of parameters named CustomerId, and another with ProductId combinations...
List<List<TestParam>> parameterList = new List<List<TestParam>>();
foreach (var x in distinctParameterNames) {
// Loop
List<TestParam> parameter = new List<TestParam>();
testList.Where(paramName => paramName.Name == x).ForEach(y =>
{
parameter.Add(new TestParam() { Name = y.Name, Value = y.Value });
});
parameterList.Add(parameter);
}
//首先获取不同的唯一参数集合的列表。。。
List distinctParameterNames=新列表();
testList.GroupBy(x=>x.Name).ForEach(paramName=>{
distinctParameterNames.Add(paramName.Key);
});
//计数
列表组合列表=新列表();
foreach(变量x在distinctParameterNames中){
Add(testList.Where(y=>y.Name==x.Count());
}
//将包含2个列表,一个包含名为CustomerId的所有参数组合,另一个包含ProductId组合。。。
列表参数List=新列表();
foreach(离散参数中的变量x){
//环路
列表参数=新列表();
testList.Where(paramName=>paramName.Name==x).ForEach(y=>
{
Add(newtestparam(){Name=y.Name,Value=y.Value});
});
parameterList.Add(参数);
}
这将是列表之间的交叉点,最终结果将是列表列表,每个列表将具有以下组合。。。因此运行将返回(在本例中):
最有效和通用的方法是什么 像这样先获取所有客户列表
var customers = from a in testlist where a.name='customerid'
select a;
var products = from a in testlist where a.name='productid'
select a;
然后循环客户
for(var c in customers)
{
loop products
for(var p in products)
{
var customerproducts = new CustomerProducts{
Customer = c.Name +' ' + c.Value
Product = p.Name + ' ' + p.value
};
then add it into a list
}
}
列表需要按
名称
分组,然后可以根据组数将其加入几次:
var groups = testList.GroupBy(_ => _.Name);
IEnumerable<IEnumerable<TestParam>> result = null;
foreach (var g in groups)
{
var current = g.Select(_ => new[] { _ });
if (result == null)
{
result = current;
continue;
}
result = result.Join(current, _ => true, _ => true, (actual, c) => actual.Concat(c));
}
// check result
foreach (var i in result)
{
Console.WriteLine(string.Join(", ", i.Select(_ => string.Format("{0}-{1}", _.Name, _.Value))));
}
var-groups=testList.GroupBy(=>u.Name);
IEnumerable结果=null;
foreach(组中的变量g)
{
var current=g.Select(=>new[]{});
如果(结果==null)
{
结果=电流;
继续;
}
result=result.Join(current,=>true,=>true,(actual,c)=>actual.Concat(c));
}
//检查结果
foreach(结果中的var i)
{
Console.WriteLine(string.Join(“,”,i.Select(=>string.Format(“{0}-{1}”,0.Name,0.Value)));
}
以下是我一直在寻找的解决方案
public static List<List<T>> AllCombinationsOf<T>(params List<T>[] sets)
{
// need array bounds checking etc for production
var combinations = new List<List<T>>();
// prime the data
foreach (var value in sets[0])
combinations.Add(new List<T> { value });
foreach (var set in sets.Skip(1))
combinations = AddExtraSet(combinations, set);
return combinations;
}
private static List<List<T>> AddExtraSet<T>
(List<List<T>> combinations, List<T> set)
{
var newCombinations = from value in set
from combination in combinations
select new List<T>(combination) { value };
return newCombinations.ToList();
}
这个解决方案不是泛型的,如果在同一个列表中有几个不同的参数具有不同的名称,那么它就不起作用。上面我发布的代码片段只是一个例子。如果我在上面的列表中添加另一个名称为Manager、值为1的条目,我需要将此组合添加到每次运行中?你是说名单?为什么没有产品Id 1和所有的产品?(如果你想要所有的组合)第一个值有什么特别的吗?@Magnus结果将是一个列表。它是列表中所有不同名称之间的交叉集。如果我有ProductId、ManagerId和CustomerId,我会根据列表中的值得到所有的组合。我认为我的解决方案更好,因为a)它做同样的事情b)它短了3倍
public static List<List<T>> AllCombinationsOf<T>(params List<T>[] sets)
{
// need array bounds checking etc for production
var combinations = new List<List<T>>();
// prime the data
foreach (var value in sets[0])
combinations.Add(new List<T> { value });
foreach (var set in sets.Skip(1))
combinations = AddExtraSet(combinations, set);
return combinations;
}
private static List<List<T>> AddExtraSet<T>
(List<List<T>> combinations, List<T> set)
{
var newCombinations = from value in set
from combination in combinations
select new List<T>(combination) { value };
return newCombinations.ToList();
}
var intersection = AllCombinationsOf(parameterList.ToArray());