Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/301.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 获取按名称分组的列表的所有组合_C#_.net_Ienumerable_Generic List - Fatal编程技术网

C# 获取按名称分组的列表的所有组合

C# 获取按名称分组的列表的所有组合,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" });

我有以下TestParam列表。。。这只是一个参数列表,用于确定如何运行查询。在以下情况下,将针对不同参数的所有组合执行预期结果。因此,列表列表中包含CustomerId 33以及列表中可用的每个产品Id

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(参数);
}
这将是列表之间的交叉点,最终结果将是列表列表,每个列表将具有以下组合。。。因此运行将返回(在本例中):

  • 客户33,产品Id 1
  • 客户33,产品Id 2
  • 客户33,产品Id 3
  • 客户33,产品Id 4
  • 客户33,产品Id 5
  • 客户33,产品Id 6
  • 客户33,产品Id 7
  • 客户33,产品Id 8

  • 最有效和通用的方法是什么

    像这样先获取所有客户列表

    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());