Поскольку вам кажется, что вы хотите сопоставить целые слова, вы можете использовать HashSet
для более эффективного поиска и предотвращения повторения list1
и list2
более одного раза.
HashSet<string> species =
new HashSet<string>(list1);
List<string> result = new List<string>();
foreach (string animal in list2)
{
if (animal.Split(' ').Any(species.Contains))
result.Add(animal);
}
ЕслиЯ запускаю это (с list1
, содержащим 1000 элементов и list2
, содержащим 100 000 элементов) на 4-ядерном ноутбуке:
The algorithm in the question: 37 seconds
The algorithm using AsParallel: 7 seconds
This algorithm: 0.17 seconds
С 1 миллионом элементов в list2
этот алгоритм занимает около секунды.
Теперь, пока этот подход работает, он может давать неверные результаты.Если list1
содержит Лев , то к результатам будет добавлен Морской лев в list2
, даже если в list1
его нет.(Если вы используете StringComparer
без учета регистра в HashSet
, как предложено ниже.)
Чтобы решить эту проблему, вам понадобится какой-то способ разобрать строки в list2
в более сложный объект Animal
.Если вы можете контролировать свой ввод, это может быть тривиальной задачей, но в целом это сложно.Если у вас есть какой-то способ сделать это, вы можете использовать решение, подобное следующему:
public class Animal
{
public string Color { get; set; }
public string Species { get; set; }
public string Breed { get; set; }
}
, а затем искать виды в HashSet
.
HashSet<string> species = new HashSet<string>
{
"Cat",
"Dog",
// etc.
};
List<Animal> animals = new List<Animal>
{
new Animal {Color = "Gray", Species = "Cat"},
new Animal {Color = "Green", Species = "Duck"},
new Animal {Color = "White", Species = "Horse"},
new Animal {Color = "Yellow", Species = "Dog", Breed = "Tasmania"}
// etc.
};
var result = animals.Where(a => species.Contains(a.Species));
Обратите внимание, что поиск строки в HashSet
чувствителен к регистру, если вы не хотите, чтобы вы могли указать StringComparer
в качестве аргумента конструктора:
new HashSet<string>(StringComparer.CurrentCultureIgnoreCase)