2010-08-26 13 views

Antwort

28

Ja, es ist möglich. Eric Lippert hat einen sehr guten Artikel zu diesem Thema:

Computing a Cartesian Product with LINQ

Wenn Sie nur zwei Listen haben, dann könnte man direkt mehr from wie folgt verwenden:

from a in s1 
from b in s2 
select new [] { a, b}; 

oder sogar:

s1.SelectMany(a => s2.Select(b => new [] { a, b })); 

Aber die Lösung von Eric Lippert im vorherigen Artikel angegebenen können Ihnen das kartesische Produkt aus mehreren Sequenzen berechnen. Mit der folgenden Erweiterungsmethode:

public static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
    IEnumerable<IEnumerable<T>> emptyProduct = new[] { Enumerable.Empty<T>() }; 
    return sequences.Aggregate(
     emptyProduct, 
     (accumulator, sequence) => 
     from accseq in accumulator 
     from item in sequence 
     select accseq.Concat(new[] { item })); 
} 

könnten Sie schreiben:

var l1 = new[] {1, 2}; 
var l2 = new[] {4, 5, 6}; 
var l3 = new[] {7, 3}; 

foreach (var result in new []{l1,l2,l3}.CartesianProduct()) 
{ 
    Console.WriteLine("{"+string.Join(",",result)+"}"); 
} 

Und erhalten:

{1,4,7} 
{1,4,3} 
{1,5,7} 
{1,5,3} 
{1,6,7} 
{1,6,3} 
{2,4,7} 
{2,4,3} 
{2,5,7} 
{2,5,3} 
{2,6,7} 
{2,6,3} 
4

Eric Lippert es bereits für Sie erledigt!

http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx

Sie wollen wahrscheinlich nur auf die Linq fließend Syntax von SelectMany

var s1 = new[] {a, b}; 
var s2 = new[] {x, y, z}; 


var product = 
from first in s1 
from second in s2 
select new[] { first, second }; 

product.SelectMany(o=>o);

oder Erics Blog-Post Version

static IEnumerable<IEnumerable<T>> CartesianProduct<T>(this IEnumerable<IEnumerable<T>> sequences) 
{ 
    // base case: 
    IEnumerable<IEnumerable<T>> result = new[] { Enumerable.Empty<T>() }; 
    foreach(var sequence in sequences) 
    { 
    var s = sequence; // don't close over the loop variable 
    // recursive case: use SelectMany to build the new product out of the  old one 
    result = 
     from seq in result 
     from item in s 
     select seq.Concat(new[] {item}); 
    } 
    return result; 
} 

product.CartesianProduct();

-3

Sie wollen

l1.Join(l2, a => 1, b => 1, (a, b) => new [] { a, b }); 
+0

ist, für was ist der Join? –

+0

Join ist für diese Operation nicht notwendig und könnte sogar ein wenig mehr Overhead verursachen (zitieren Sie mich nicht in diesem letzten Teil). Die anderen Antworten zeigen etwas intuitiver. –

+0

es funktioniert, Zeitraum –

3
var result = from a in l1 
      from b in l2 
      select new[] { a, b } 
1

Großer Artikel von Eric Lippert - siehe Links in anderen Antworten. Was noch besser ist, war dies der erste Versuch ich vor bei den Antworten auf dieser Seite :) Suche hat

Kurz:

var rez = 
    from e1 in l1 
    from e2 in l2 
    select new {e1, e2}; 
1

so etwas wie dies tun wird, was Sie suchen.

var l1 = new List<int>{1,2}; 
var l2 = new List<int>{4,5,6}; 

var p = from n in l1 
     from m in l2 
     select new { Fst = n, Scd = m }; 

mit dieser Antwort Ihre Tupeln {x, y} ist ein anonymer Typ.

Verwandte Themen