The most convenient would be
var Z = X.Where(x => !x.Split('.').Intersect(Y).Any()).ToList();
That is not the same as "fastest". Probably the fastest (runtime) way to do that is to use a token search, like:
public static bool ContainsToken(string value, string token, char delimiter = '.')
{
if (string.IsNullOrEmpty(token)) return false;
if (string.IsNullOrEmpty(value)) return false;
int lastIndex = -1, idx, endIndex = value.Length - token.Length, tokenLength = token.Length;
while ((idx = value.IndexOf(token, lastIndex + 1)) > lastIndex)
{
lastIndex = idx;
if ((idx == 0 || (value[idx - 1] == delimiter))
&& (idx == endIndex || (value[idx + tokenLength] == delimiter)))
{
return true;
}
}
return false;
}
then something like:
var list = new List<string>(X.Length);
foreach(var x in X)
{
bool found = false;
foreach(var y in Y)
{
if(ContainsToken(x, y, '.'))
{
found = true;
break;
}
}
if (!found) list.Add(x);
}
This:
- doesn't allocate arrays (for the output of
Split, of for the params char[] of Split)
- doesn't create any new
string instances (for the output of Split)
- doesn't use delegate abstraction
- doesn't have captured scopes
- uses the
struct custom iterator of List<T> rather than the class iterator of IEnumerable<T>
- starts the new
List<T> with the appropriate worst-case size to avoid reallocations