There are two lists {a, b, c, a, d, a, e} and {a, c, a}. I need to remove those elements from the first list which appears in a second list, to get {b, d, a, e}
|
Here somewhat longer but also a bit more efficient:
This avoids incrementing counters for elements that will never be dropped. With some data this is not too far behind Leonid's method:
Where there is heavy duplication Leonid's method is still much faster than mine. |
|||||||||||||||||
|
or
|
||||
|
|
ImplementationI am sure I missed a more elegant / short version, but here is an implementation which will be efficient even for large lists:
It borrows main ideas from here, but modifies it to the needs of the problem at hand. Once position intervals for elements in the sorted main list are found, they are shrinked by the number of same elements present in the second list, from the start (from the left end). From this, I generate partial list of positions in the ordered list, and reverse that via the ordering of that list, to get a list of positions in the original list. The algorithm has a log-linear complexity in the length of the first list and linear complexity in the length of the second list. Examples and benchmarksWe have
for larger lists:
|
|||
|
|
|
Here's a slightly unconventional solution using patterns, and is very compact too:
This exploits the fact that by default, |
|||||||||||||
|
|
In Mathematica 9.0.0 there are several undocumented functions for dealing with hash maps explicitly.
Here is the solution based on these functions:
But for this particular question solutions by Leonid and Mr.Wizard are faster. |
|||
|
|


