item index generic ejemplos create array c# linq generics list combinations

c# - index - Combinación de List<List<int>>



public list c# (7)

¿Qué tal la siguiente forma de generar combinaciones usando el método .Join?

static void Main() { List<List<int>> collectionOfSeries = new List<List<int>> { new List<int>(){1, 2, 3, 4, 5}, new List<int>(){0, 1}, new List<int>(){6,3}, new List<int>(){1,3,5} }; int[] result = new int[collectionOfSeries.Count]; List<List<int>> combinations = GenerateCombinations(collectionOfSeries); Display(combinations); }

Este método GenerateCombinations (..) hace el trabajo principal de generar combinaciones. Este método es genérico, por lo que podría usarse para generar combinaciones de cualquier tipo.

private static List<List<T>> GenerateCombinations<T>( List<List<T>> collectionOfSeries) { List<List<T>> generatedCombinations = collectionOfSeries.Take(1) .FirstOrDefault() .Select(i => (new T[]{i}).ToList()) .ToList(); foreach (List<T> series in collectionOfSeries.Skip(1)) { generatedCombinations = generatedCombinations .Join(series as List<T>, combination => true, i => true, (combination, i) => { List<T> nextLevelCombination = new List<T>(combination); nextLevelCombination.Add(i); return nextLevelCombination; }).ToList(); } return generatedCombinations; }

Mostrar ayudante ..

private static void Display<T>(List<List<T>> generatedCombinations) { int index = 0; foreach (var generatedCombination in generatedCombinations) { Console.Write("{0}/t:", ++index); foreach (var i in generatedCombination) { Console.Write("{0,3}", i); } Console.WriteLine(); } Console.ReadKey(); }

Tengo una Lista de este tipo Lista> que contiene esto

List<int> A = new List<int> {1, 2, 3, 4, 5}; List<int> B = new List<int> {0, 1}; List<int> C = new List<int> {6}; List<int> X = new List<int> {....,....};

Quiero tener todas las combinaciones como esta

1-0-6 1-1-6 2-0-6 2-1-6 3-0-6

y así.

Según usted, ¿es posible resolver esto usando Linq?


Es bastante similar a esta respuesta que le di a otra pregunta:

var combinations = from a in A from b in B from c in C orderby a, b, c select new List<int> { a, b, c }; var x = combinations.ToList();

Para una cantidad variable de entradas, ahora con genéricos añadidos:

var x = AllCombinationsOf(A, B, C); 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(); }


Gran solución de Abhijeet Nagre. Pequeña mejora en caso de que alguna serie esté vacía o las series estén vacías.

List<List<T>> generatedCombinations = collectionOfSeries.Where(l => l.Any()) .Take(1) .DefaultIfEmpty(new List<T>()) .First() .Select(i => (new T[]{i}).ToList()) .ToList();


Si el número de dimensiones es fijo, esto es simplemente SelectMany :

var qry = from a in A from b in B from c in C select new {A=a,B=b,C=c};

Sin embargo, si la cantidad de dimensiones está controlada por los datos, debe usar la recursión:

static void Main() { List<List<int>> outerList = new List<List<int>> { new List<int>(){1, 2, 3, 4, 5}, new List<int>(){0, 1}, new List<int>(){6,3}, new List<int>(){1,3,5} }; int[] result = new int[outerList.Count]; Recurse(result, 0, outerList); } static void Recurse<TList>(int[] selected, int index, IEnumerable<TList> remaining) where TList : IEnumerable<int> { IEnumerable<int> nextList = remaining.FirstOrDefault(); if (nextList == null) { StringBuilder sb = new StringBuilder(); foreach (int i in selected) { sb.Append(i).Append('',''); } if (sb.Length > 0) sb.Length--; Console.WriteLine(sb); } else { foreach (int i in nextList) { selected[index] = i; Recurse(selected, index + 1, remaining.Skip(1)); } } }


Solo por diversión:

using CSScriptLibrary; using System; using System.Collections.Generic; namespace LinqStringTest { public class Program { static void Main(string[] args) { var lists = new List<List<int>>() { new List<int> { 0, 1, 2, 3 }, new List<int> { 4, 5 }, new List<int> { 6, 7 }, new List<int> { 10,11,12 }, }; var code = GetCode(lists); AsmHelper scriptAsm = new AsmHelper(CSScript.LoadCode(code)); var result = (IEnumerable<dynamic>)scriptAsm.Invoke("Script.LinqCombine", lists); foreach (var item in result) { Console.WriteLine(item); } Console.ReadLine(); } private static string GetCode(List<List<int>> listsToCombine) { var froms = ""; var selects = ""; for (int i = 0; i < listsToCombine.Count; i++) { froms += string.Format("from d{0} in lists[{0}]{1}", i, Environment.NewLine); selects += string.Format("D{0} = d{0},", i); } return @"using System; using System.Linq; using System.Collections.Generic; public class Script { public static IEnumerable<dynamic> LinqCombine(List<List<int>> lists) { var x = " + froms + @" select new { " + selects + @" }; return x; } }"; } } }


public static List<List<string>> CrossProduct(List<List<string>> s) { if (!s.Any()) return new List<List<string>>(); var c1 = s.First(); var cRest = s.Skip(1).ToList(); var sss = from v1 in c1 from vRest in CrossProduct(cRest) select (new[] { v1 }.Concat(vRest)).ToList(); var r = sss.ToList(); return r; }


//Done in 2 while loops. No recursion required #include<stdio.h> #define MAX 100 typedef struct list { int elements[MAX]; }list; list n[10]; int number,count[10],temp[10]; void print(); int main() { int i,j,mult=1,mult_count; printf("Enter the number of lists - "); scanf("%d",&number); for(i=0;i<number;i++) { printf("Enter the number of elements - "); scanf("%d",&count[i]); for(j=0;i<count[i];j++) { printf("Enter element %d - "j); scanf("%d",&n[i].elements[j]); } } for(i=0;i<number;i++) temp[i]=0; for(i=0;i<number;i++) mult*=count[i]; printf("%d/n",mult); mult_count=0; while(1) { print(); mult_count++; if(mult_count==mult) break; i=0; while(1) { temp[i]++; if(temp[i]==count[i]) { temp[i]=0; i++; } else break; } } return 0; } void print() { int i; for(i=0;i<number;i++) { printf("%d/n",n[i].elements[temp[i]]); printf("/n"); } }