//Here I have a List of Lists
List<List<T>> SelectionList = new List<List<T>>();
//My current code to compare lists
for(int i = 0; i < SelectionList.Count; i++)
{
for(int j = 0; j < SelectionList.Count; j++)
{
if (SelectionList[i].Equals(SelectionList[j]))
{
SelectionList.Remove(SelectionList[j]);
}
}
}
//Note: The above code supposedly works, in cases where the contents of both the lists are ordered ie., they are in same index, but in my lists they might be same but list contents are shuffled. in this case it fails to identify.
//Basically I need to remove any repetitions of same list in my list of lists;
If (and only if) the following is true:
T
of your list elements implements IComparable
and GetHashCode()
correctlyThen you can remove each list that matches an earlier list like so (note that you must traverse the list backwards when removing items from the end of it otherwise the loop indices could go out of range):
for (int i = lists.Count - 1; i > 0; i--)
{
for (int j = i - 1; j >= 0; j--)
{
if (!lists[i].Except(lists[j]).Any())
{
lists.RemoveAt(i);
break;
}
}
}
The important line here is: !lists[i].Except(lists[j]).Any()
.
Let's break it down:
lists[i].Except(lists[j])
: - This produces a sequence of all the elements of lists[i]
that are NOT in lists[j]
, regardless of order.
Thus if all of the items in lists[j]
are also in lists[j]
, this will produce an empty sequence; otherwise, it will produce a non-empty sequence.
The .Any()
will return true
for a non-empty sequence, and false
for an empty sequence.
So lists[i].Except(lists[j]).Any()
will return false
if the items are the same in each list and true
if they differ.
This is the opposite of what we want for the lists.RemoveAt()
so we just negate the result, giving the final code !lists[i].Except(lists[j]).Any()
.
Compilable console app:
using System;
using System.Collections.Generic;
using System.Linq;
static class Program
{
static void Main()
{
var lists = new List<List<int>>
{
new() {1, 2, 3, 4, 5}, // [0]
new() {2, 3, 4, 5, 6}, // [1]
new() {3, 4, 5, 6, 7}, // [2]
new() {5, 4, 3, 2, 1}, // [3] Dupe of [0]
new() {4, 5, 6, 7, 8}, // [4]
new() {6, 5, 4, 3, 2}, // [5] Dupe of [1]
new() {5, 6, 7, 8, 9}, // [6]
new() {3, 4, 5, 2, 1}, // [7] Dupe of [0]
new() {6, 7, 8, 9, 0} // [8]
};
for (int i = lists.Count - 1; i > 0; i--)
{
for (int j = i - 1; j >= 0; j--)
{
if (!lists[i].Except(lists[j]).Any())
{
lists.RemoveAt(i);
break;
}
}
}
for (int i = 0; i < lists.Count; ++i)
{
Console.WriteLine(string.Join(", ", lists[i]));
}
}
Try it on DotNetFiddle: https://dotnetfiddle.net/nWnOcP