I have a rather specific question about how to exclude items of one list from another. Common approaches such as Except() won’t do and here is why:
- If the duplicate within a list has an “even” index – I need to remove THIS element and the NEXT element AFTER it.
- if the duplicate within a list had an “odd” index – I need to remove THIS element AND one element BEFORE** it.
- there might be many appearances of the same duplicate within a list. i.e. one might be with an “odd” index, another – “even”.
I’m not asking for a solution since I’ve created one myself. However after performing this method many times – “ANTS performance profiler” shows that the method elapses 75% of whole execution time (30 seconds out of 40). The question is: Is there a faster method to perform the same operation? I’ve tried to optimize my current code but it still lacks performance. Here it is:
private void removedoubles(List<int> exclude, List<int> listcopy)
{
for (int j = 0; j < exclude.Count(); j++)
{
for (int i = 0; i < listcopy.Count(); i++)
{
if (listcopy[i] == exclude[j])
{
if (i % 2 == 0) // even
{
//listcopy.RemoveRange(i, i + 1);
listcopy.RemoveAt(i);
listcopy.RemoveAt(i);
i = i - 1;
}
else //odd
{
//listcopy.RemoveRange(i - 1, i);
listcopy.RemoveAt(i - 1);
listcopy.RemoveAt(i - 1);
i = i - 2;
}
}
}
}
}
where:
- exclude – list that contains Duplicates only. This list might contain up to 30 elements.
- listcopy – list that should be checked for duplicates. If duplicate from “exclude” is found -> perform removing operation. This list might contain up to 2000 elements.
I think that the LINQ might be some help but I don’t understand its syntax well.
A faster way (
O(n)) would be to do the following:excludelist and make it into aHashSet(O(n))O(n)), since test for presence in aHashSetisO(1).Maybe you can even change your algorithms so that the
excludecollection will be aHashSetfrom the very beginning, this way you can omit step 1 and gain even more speed.(Your current way is
O(n^2).)Edit:
Another idea is the following: you are perhaps creating a copy of some list and make this method modify it? (Guess based on the parameter name.) Then, you can change it to the following: you pass the original array to the method, and make the method allocate new array and return it (your method signature should be than something like
private List<int> getWithoutDoubles(HashSet<int> exclude, List<int> original)).Edit:
It could be even faster if you would reorganize the input data in the following way: As the items are always removed in pairs (even index + the following odd index), you should pair them in advance! So that your list if ints becomes list of pairs of ints. This way your method might be be something like that:
(you remove the pairs where either the first or the second item is in the exclude collection). Instead of
Tuple, perhaps you can pack the items into your custom type.