How to remove duplicate pairs in a List
You could use a custom IEqualityComparer<FaceLine>
:
public class UnorderedFacelineComparer : IEqualityComparer<FaceLine>
{
public bool Equals(FaceLine x, FaceLine y)
{
int x1 = Math.Min(x.A, x.B);
int x2 = Math.Max(x.A, x.B);
int y1 = Math.Min(y.A, y.B);
int y2 = Math.Max(y.A, y.B);
return x1 == y1 && x2 == y2;
}
public int GetHashCode(FaceLine obj)
{
return obj.A ^ obj.B;
}
}
Then the query was very simple:
var comparer = new UnorderedFacelineComparer();
List<FaceLine> nonDupList = faceLine
.GroupBy(fl => fl, comparer)
.Where(g => g.Count() == 1)
.Select(g => g.First())
.ToList();
If you wanted to keep one of the duplicates you just need to remove the Where
:
List<FaceLine> nonDupList = faceLine
.GroupBy(fl => fl, comparer)
.Select(g => g.First())
.ToList();
Using Linq :
List<List<int>> data = new List<List<int>>() {
new List<int>() {1, 2},
new List<int>() {2, 3},
new List<int>() {3, 1},
new List<int>() {3, 2},
new List<int>() {2, 4},
new List<int>() {4, 3}
};
List<List<int>> results =
data.Select(x => (x.First() < x.Last())
? new { first = x.First(), last = x.Last() }
: new { first = x.Last(), last = x.First() })
.GroupBy(x => x)
.Select(x => new List<int>() { x.First().first, x.First().last }).ToList();
If you're happy using the common DistinctBy
Linq extension (available via NuGet) you can do this fairly simply like so:
var result = list.DistinctBy(x => (x.A > x.B) ? (x.A, x.B) : (x.B, x.A));
Sample console app:
using System;
using System.Collections.Generic;
using MoreLinq;
namespace Demo
{
class Test
{
public Test(int a, int b)
{
A = a;
B = b;
}
public readonly int A;
public readonly int B;
public override string ToString()
{
return $"A={A}, B={B}";
}
}
class Program
{
static void Main()
{
var list = new List<Test>
{
new Test(1, 2),
new Test(2, 3),
new Test(3, 1),
new Test(3, 2),
new Test(2, 4),
new Test(4, 3)
};
var result = list.DistinctBy(x => (x.A > x.B) ? (x.A, x.B) : (x.B, x.A));
foreach (var item in result)
Console.WriteLine(item);
}
}
}