Reputation: 151
How do I remove duplicate inner lists from main list?
var list1 = new List<object>() { 1,2,3 };
var list2 = new List<object>() { 4,5,6 };
var list3 = new List<object>() { 1,2,3 };
List<List<object>> mainList = new List<List<object>>() {list1, list2, list3};
I want to remove the list3
from the mainList
so that no duplicates in the mainList
.
Upvotes: 3
Views: 2965
Reputation: 305
try following linq uery
var list1 = new List<object>() { 1, 2, 3 };
var list2 = new List<object>() { 4, 5, 6 };
var list3 = new List<object>() { 3, 1, 2 };
List<List<object>> mainList = new List<List<object>>() { list1, list2, list3 };
var distinctlist = mainList.Select(o =>
{
var t = o.OrderBy(x=>x).Select(i => i.ToString());
return new { Key= string.Join("", t),List=o };
})
.GroupBy(o => o.Key)
.Select(o => o.FirstOrDefault())
.Select(o => o.List);
Upvotes: 0
Reputation: 19169
Update: as mentioned in comments, order of items does not matter so {3,2,1}
and {1,2,3}
are considered duplicate.
There are a few concerns about your question. your inner list contains objects. if that means object can be anything and not just an int
then you should make sure those objects override Equals
and GetHashCode
as well (or implement IEquatable<TSelf>
where TSelf
is the implementing type).
If your inner list just contains primitive types or common readonly structs such as DateTime or TimeSpan then you shouldn't worry.
You can use Distinct and EqualityComparer interface
var list1 = new List<object>() { 1, 2, 3 };
var list2 = new List<object>() { 4, 5, 6 };
var list3 = new List<object>() { 1, 2, 3 };
List<List<object>> mainList = new List<List<object>>() { list1, list2, list3 };
mainList = mainList.Distinct(ListEqualityComparer<object>.Default).ToList();
Equality comparer implementation.
public class ListEqualityComparer<T> : IEqualityComparer<List<T>>
{
private readonly IEqualityComparer<T> _itemEqualityComparer;
public ListEqualityComparer() : this(null) { }
public ListEqualityComparer(IEqualityComparer<T> itemEqualityComparer)
{
_itemEqualityComparer = itemEqualityComparer ?? EqualityComparer<T>.Default;
}
public static readonly ListEqualityComparer<T> Default = new ListEqualityComparer<T>();
public bool Equals(List<T> x, List<T> y)
{
if (ReferenceEquals(x, y)) return true;
if (ReferenceEquals(x, null) || ReferenceEquals(y, null)) return false;
return x.Count == y.Count && !x.Except(y, _itemEqualityComparer).Any();
}
public int GetHashCode(List<T> list)
{
int hash = 17;
foreach (var itemHash in list.Select(x => _itemEqualityComparer.GetHashCode(x))
.OrderBy(h => h))
{
hash += 31 * itemHash;
}
return hash;
}
}
If your objects does not override Equals
and GetHashCode
you can make another equality comparer for your items as well and pass it to this equality comparer.
mainList = mainList.Distinct(new ListEqualityComparer<object>(myItemEqualityComparer)).ToList();
where myItemEqualityComparer
is for comparing your object
s
Upvotes: 6