Getting Pair-Set Using Linq

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

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 get all possible pair of connections from two lists

Updated Answer

This should do it:

using System.Linq;
using static System.Console;

class Program {
static void Main(string[] args) {
var inputs = new[] { "A", "B", "C" };
var outputs = new[] { "1", "2", "3", "4" };

var res = from i1 in inputs
from i2 in inputs
where i1 != i2
from o1 in outputs
from o2 in outputs
where o1 != o2
let c1 = i1 + o1
let c2 = i2 + o2
// Avoid {x,y} and {y,x} in result.
where c1.CompareTo(c2) < 0
select (first: c1, second: c2);

foreach (var r in res) {
WriteLine($"{{{r.first}, {r.second}}}");
}
}
}

Original Answer

You need the LINQ to Objects equivalent of a cross join, which is just looping over the contents of both lists without any conditions to limit the set of results.

var allPairs = (from a in ListA
from b in ListB
select (a, b)
).ToList();

Will give you a list of all pairs as tuples.

In your case you seem to want all pairs of pairs: given all combinations of input and output then get all pairs of combinations on input and output.

Which is just a case of expanding the above with a second combination of the list of all input-output combinations.

// Assume `Input` and `Output` and enumerables of string
var inputOutputPairs = (from ip in Input
from op in Output
select ip + op
).ToList();

var result = (from left in inputOutputPairs
from right in inputOutputPairs
select (left, right)
// To avoid duplicates like ("A4","A4") include this:
// where left != right
).ToList();

And the result will be a list of ValueTuple<string, string>.

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.

Use linq to match up pairs of rows in a set

class Program
{
static void Main(string[] args)
{
IEnumerable<DataRow> rows = new[]
{
new DataRow(1,"fish",""),
new DataRow(1,"fish","D"),
new DataRow(2,"cat","A"),
new DataRow(3,"fox",""),
new DataRow(3,"dog","U"),
new DataRow(4,"mouse","")
};

var result = rows
.GroupBy(x => x.Id)
.Select(g => new
{
Count = g.Count(),
Id = g.First().Id,
FirstRow = g.First(),
LastRow = g.Last()
}).Select(item => new
{
RowId = item.Id,
OldData = item.Count == 1 && item.FirstRow.RowMod != "" ? null : item.FirstRow.Data,
NewData = item.LastRow.RowMod == "D" ? null : item.LastRow.Data,
RowMod = item.LastRow.RowMod
});

//Or using query syntax
var result2 = from x in rows
orderby x.Id, x.RowMod
group x by x.Id into g
select new
{
RowId = g.First().Id,
OldData = g.Count() == 1 && g.First().RowMod != "" ? null : g.First().Data,
NewData = g.Last().RowMod == "D" ? null : g.Last().Data,
RowMod = g.Last().RowMod
};

// Test
Console.WriteLine("RowID\tOldData\tNewData\tRowMod");
foreach (var item in result)
{
Console.WriteLine("{0}\t'{1}'\t'{2}'\t'{3}'",item.RowId,item.OldData ?? "null",item.NewData ?? "null",item.RowMod);
}
}
}

public class DataRow
{
public int Id { get; set; }
public string Data { get; set; }
public string RowMod { get; set; }

public DataRow(int id, string data, string rowMod)
{
Id = id;
Data = data;
RowMod = rowMod;
}
}

Output:

RowID   OldData NewData RowMod
1 'fish' 'null' 'D'
2 'null' 'cat' 'A'
3 'fox' 'dog' 'U'
4 'mouse' 'mouse' ''

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 alternate pairs using LINQ

I'm not sure whether it is what you need:

public static void Main()
{
List<RelationDTO> relationDTOList = new List<RelationDTO>
{
new RelationDTO { PersonId = 1, RelativeId = 2, Relation = "Son" },
new RelationDTO { PersonId = 2, RelativeId = 1, Relation = "Father" },

new RelationDTO { PersonId = 1, RelativeId = 3, Relation = "Mother" },
new RelationDTO { PersonId = 3, RelativeId = 1, Relation = "Son" },

new RelationDTO { PersonId = 2, RelativeId = 3, Relation = "Husband" },
new RelationDTO { PersonId = 3, RelativeId = 2, Relation = "Wife" },
};

var grp = relationDTOList.Join(relationDTOList,
dto => dto.PersonId + "-" + dto.RelativeId,
dto => dto.RelativeId + "-" + dto.PersonId,
(dto1, dto2) => new Relations
{
PersonId = dto1.PersonId,
RelationId = dto1.RelativeId,
Relation = dto1.Relation,
ReverseRelation = dto2.Relation
}).Distinct(new MyEqualityComparer());

foreach (var g in grp)
Console.WriteLine("{0},{1},{2},{3}", g.PersonId, g.RelationId, g.Relation, g.ReverseRelation);
}

public class MyEqualityComparer : IEqualityComparer<Relations>
{
public bool Equals(Relations x, Relations y)
{
return x.PersonId + "-" + x.RelationId == y.PersonId + "-" + y.RelationId ||
x.PersonId + "-" + x.RelationId == y.RelationId + "-" + y.PersonId;
}

public int GetHashCode(Relations obj)
{
return 0;
}
}

Using linq to retrieve pairs of Points from collection?

I'm off out in a second, but here's a horrible solution (in that it uses side-effects):

Point previous = default(Point);

return points.Select(p => { Point tmp = previous;
previous = p;
return new { p1 = tmp, p2 = previous };
})
.Skip(1); // Ignore first (invalid) result

You can probably do better with System.Interactive and Scan, but otherwise it would probably be best to write a new extension method. Something like this (using Tuple from C# 4):

public static IEnumerable<Tuple<T, T>> ConsecutivePairs<T>(this IEnumerable<T> sequence)
{
// Omitted nullity checking; would need an extra method to cope with
// iterator block deferred execution
using (IEnumerator<T> iterator = sequence.GetEnumerator())
{
if (!iterator.MoveNext())
{
yield break;
}
T previous = iterator.Current;
while (iterator.MoveNext())
{
yield return Tuple.Create(previous, iterator.Current);
previous = iterator.Current;
}
}
}

(Apologies for any mistakes - written in a hurry!)

LINQ: Get all pairs from a dictionary where pair.key is in a string array

If I understand well, what you need is this:

var parameters = Parameters.Where(p=>step.Variables.Contains(p.Key))
.ToDictionary(p=>p.Key,p.Value);

You need to filter first the Parameter dictionary to see if the key is in the Variables collection and convert the result, which is IEnumerable<KeyValuePair<string, string>>, into a Dictionary<string, string>

EntityFramework - Group by unordered pair in LINQ query

In GroupBy you can create a conditional key so when you want to group by a pair of values where order dosen't matter you can construct key as an anonymous type with the first property set to min value and the second to max value.

var all = from m in db.Peers
where m.User_Id_To == id || m.User_Id_From == id
group m by new
{
Min = m.User_Id_To < m.User_Id_From ? m.User_Id_To : m.User_Id_From,
Max = m.User_Id_To > m.User_Id_From ? m.User_Id_To : m.User_Id_From
}
into g
select g.OrderByDescending(x => x.Date).FirstOrDefault();


Related Topics



Leave a reply



Submit