Reputation: 5853
I have a List of value Tuple
as follows:
List<(int, int)> values = new List<(int, int)>
{
(12, 15),
(18, 30),
(18, 27),
(27, 30)
};
Now I want to remove the pairs in this list, which is inside the range of the wider pair.
For example: (18, 27)
and (27, 30)
are in the range of (18, 30)
. So, I want to remove those pairs which lie under it.
So the final output must be:
(12, 15)
(18, 30)
I was thinking of removing those pairs using the .RemoveAll()
method of LINQ but I am stuck as how to do so.
Any help will be appreciated.
Upvotes: 0
Views: 309
Reputation: 2204
I believe this should work and should be n*log(n):
//You will see some Math.Max and Math.Min - these are required because in your comments
//you state the pairs can be out of order (the second value is less than the first)
int upper = int.MinValue;
values = values
//Group all pairs by their minimum value, so (18,30) and (18,27) for example
//would be processed together
.GroupBy(x => Math.Min(x.Item1, x.Item2))
//Sort the groups based on their minimum value, so they can be processed in order.
//Although your example does not require this, the comments say this is required.
.OrderBy(x => x.Key)
//From the group [which may contain (18,30) and (18,27) for example],
//only choose the one with the highest max value. This will choose (18,30)
.Select(x => x.OrderBy(y => Math.Max(y.Item1, y.Item2)).Last())
//Now iterate through the items and throw away the items which are inside
//a pair previously processed pair. We use the upper variable to
//keep track of the greatest processed upper bound to make throwing away
//previously processed pairs easy
.Where(x =>
{
var max = Math.Max(x.Item1, x.Item2);
if (upper < max)
{
upper = max;
return true;
}
else
{
return false;
}
}).ToList();
This can certainly be made faster without Linq, depending on how important memory and performance are for your application.
Upvotes: 1
Reputation: 6192
If I understood correctly this will do the trick. It compares each value of the list with the entire list till it finds another tuple where it falls within the range that's not exactly equal.
List<(int, int)> values = new List<(int, int)>
{
(12, 15),
(18, 30),
(18, 27),
(27, 30)
};
values.RemoveAll(x => values.Any(y => x.CompareTo(y) != 0 && x.Item1 >= y.Item1 && x.Item2 <= y.Item2));
Upvotes: 2