Данные списки l1 = {1 , 2}
и l2 = {4, 5, 6}
Я хочу получить новый список с элементами:
rez = { {1, 4}, {1, 5}, {1, 6}, {2, 4}, {2, 5}, {2, 6} }
Предложения?
Да, это возможно. Эрик Липперт написал очень хорошую статью на эту тему:
Вычисление декартова произведения с помощью LINQ
Если у вас есть только 2 списка, вы можете напрямую использовать несколько из
следующим образом:
from a in s1
from b in s2
select new [] { a, b};
или даже:
s1.SelectMany(a => s2.Select(b => new [] { a, b }));
Но решение, данное Эриком Липпертом в предыдущей статье, позволяет вычислить декартово произведение нескольких последовательностей. С помощью следующего метода расширения:
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 }));
}
Вы можете написать:
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)+"}");
}
И получить:
{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}
Эрик Липперт уже сделал это за вас!
http://blogs.msdn.com/b/ericlippert/archive/2010/06/28/computing-a-cartesian-product-with-linq.aspx
вы, вероятно, просто хотите использовать свободный синтаксис linq из 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);
или сообщение в блоге Эрика 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();
Вы хотите
l1.Join(l2, a => 1, b => 1, (a, b) => new [] { a, b });
что-то вроде этого сделает то, что вы ищете.
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 };
с этим ответом ваши кортежи {x,y} являются анонимными.
Вот, пожалуйста;
var rez = from first in l1
from second in l2
select new[] { first, second };
Отличная статья Эрика Липперта - см. ссылки в других ответах. Что еще лучше, это была первая попытка, которую я предпринял до просмотра ответов на этой странице :)
Вкратце:
var rez =
from e1 in l1
from e2 in l2
select new {e1, e2};
var result = from a in l1
from b in l2
select new[] { a, b }