What Thread Runs the Code After the 'Await' Keyword

Linq to return ALL pairs of elements from two lists?

Yes it is possible. Eric Lippert wrote a very good article on this topic:

Computing a Cartesian Product with LINQ

If you only have 2 lists, then you could directly use multiple from like this:

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

or even:

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

But the solution given by Eric Lippert in the previous article allows you to compute the cartesian product of several sequences. With the following extension method:

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

You could write:

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)+"}");
}

And obtain:

{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}

C# & LINQ, Select two (consecutive) items at once

Another answer presents a nice and clean solution using LINQ's Skip and Zip.

It is absolutely correct, but I'd like to point out that it enumerates the source twice. That may or may not matter, depending on each individual use case. If it matters for your case, here's a longer alternative that is functionally equivalent but enumerates the source once:

static class EnumerableUtilities
{
public static IEnumerable<TResult> SelectTwo<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, TSource, TResult> selector)
{
if (source == null) throw new ArgumentNullException(nameof(source));
if (selector == null) throw new ArgumentNullException(nameof(selector));

return SelectTwoImpl(source, selector);
}

private static IEnumerable<TResult> SelectTwoImpl<TSource, TResult>(this IEnumerable<TSource> source,
Func<TSource, TSource, TResult> selector)
{
using (var iterator = source.GetEnumerator())
{
var item2 = default(TSource);
var i = 0;
while (iterator.MoveNext())
{
var item1 = item2;
item2 = iterator.Current;
i++;

if (i >= 2)
{
yield return selector(item1, item2);
}
}
}
}
}

Example:

var seq = new[] {"A", "B", "C", "D"}.SelectTwo((a, b) => a + b);

The resulting sequence contains "AB", "BC", "CD".

How can I pair up two items from a list using linq?

In .NET 6, you can use LINQ Chunk<TSource>(int size).

IEnumerable<string[]> groups = list.Chunk(2);

Using LINQ to create pairs from two different list where the entries have same attribute

Just join both sequences on RequestId and create CallPair from joined items:

 var requestWithMatches = from req in _requests
join resp in _responses
on req.RequestId equals resp.RequestId
select new CallPair(req, resp);

Group items in pairs

Well, you could do:

var pairs = sequence.Select((value, index) => new { value, index } )
.GroupBy(x => x.index / 2, x => x.value)

The result is an IGrouping<int, T> with a key of 0, 1, 2 etc and the contents of each group being one or two items.

However, I'd possibly write a custom extension method:

public static IEnumerable<Tuple<T, T>> PairUp<T>(this IEnumerable<T> source)
{
using (var iterator = source.GetEnumerator())
{
while (iterator.MoveNext())
{
var first = iterator.Current;
var second = iterator.MoveNext() ? iterator.Current : default(T);
yield return Tuple.Create(first, second);
}
}
}

This will yield a sequence of tuples - the downside here is that the final tuple will have the default value for T as the "second" item if the sequence has an odd number of items. For reference types where the sequence only consists of non-null values, that's okay, but for some sequences it wouldn't help.

Getting pair-set using LINQ

This will give you an array of anonymous "pair" objects with A and B properties corresponding to the pair elements.

var pairs = list.Where( (e,i) => i < list.Count - 1 )
.Select( (e,i) => new { A = e, B = list[i+1] } );

Get all pairs in a list using LINQ

Slight reformulation of cgeers answer to get you the tuples you want instead of arrays:

var combinations = from item1 in list
from item2 in list
where item1 < item2
select Tuple.Create(item1, item2);

(Use ToList or ToArray if you want.)

In non-query-expression form (reordered somewhat):

var combinations = list.SelectMany(x => list, (x, y) => Tuple.Create(x, y))
.Where(tuple => tuple.Item1 < tuple.Item2);

Both of these will actually consider n2 values instead of n2/2 values, although they'll end up with the correct answer. An alternative would be:

var combinations = list.SelectMany((x, i) => list.Skip(i + 1), (x, y) => Tuple.Create(x, y));

... but this uses Skip which may also not be optimized. It probably doesn't matter, to be honest - I'd pick whichever one is most appropriate for your usage.

How to use LINQ to find all combinations of n items from a set of numbers?

Usage:

var results = new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 }.DifferentCombinations(3);

Code:

public static class Ex
{
public static IEnumerable<IEnumerable<T>> DifferentCombinations<T>(this IEnumerable<T> elements, int k)
{
return k == 0 ? new[] { new T[0] } :
elements.SelectMany((e, i) =>
elements.Skip(i + 1).DifferentCombinations(k - 1).Select(c => (new[] {e}).Concat(c)));
}
}


Related Topics



Leave a reply



Submit