Trois options - les deux premiers sont plus générales, en ce qu'elles ne reposent pas sur des MillionIntegerList
triées (ce qui n'était pas initialement prévu). Le troisième est préférable dans le cas où la liste est déjà triée.
Option 1
Oui, il y a certainement une meilleure façon de le faire, à l'aide de LINQ:
var common = MillionIntegerList.Intersect(TwoThousandIntegerList).ToList();
Qui va utiliser à l'interne un HashSet<int>
construits par l'intermédiaire de l' TwoThousandIntegerList
, puis de regarder chaque élément de l' MillionIntegerList
au sein de ce qui sera beaucoup plus efficace que de passer par l'ensemble de l' TwoThousandIntegerList
à chaque fois.
Si vous voulez seulement le non sur la liste noire, vous devez:
var valid = MillionIntegerList.Except(TwoThousandIntegerList).ToList();
Notez que si vous avez seulement besoin d'itérer sur les résultats une fois, vous devez supprimer l' ToList
appelez - je l'ai inclus pour matérialiser les résultats de manière à ce qu'ils puissent être examinés à plusieurs reprises à moindre coût. Si vous êtes juste de l'itération, la valeur de retour de l' Intersect
ou Except
sera juste stream les résultats, ce qui rend beaucoup moins cher en termes de l'utilisation de la mémoire.
Option 2
Si vous ne voulez pas compter sur les détails de mise en œuvre de LINQ to Objects, mais vous voulez une base de hachage approche:
var hashSet = new HashSet<int>(TwoThousandIntegerList);
hashSet.IntersectWith(MillionIntegerList);
// Now use hashSet
Option 3
L'approche de l'aide du fait que la grande liste est triée serait certainement utile.
En supposant que vous n'avez pas l'esprit de tri de la liste noire de la liste de la première, vous pourriez écrire un streaming (et générale) de la mise en œuvre de cette façon (non testé):
// Note: to use this, you'd need to make sure that *both* sequences are sorted.
// You could either sort TwoThousandIntegerList in place, or use LINQ's OrderBy
// method.
public IEnumerable<T> SortedIntersect<T>(this IEnumerable<T> first,
IEnumerable<T> second) where T : IComparable<T>
{
using (var firstIterator = first.GetEnumerator())
{
if (!firstIterator.MoveNext())
{
yield break;
}
using (var secondIterator = second.GetEnumerator())
{
if (!secondIterator.MoveNext())
{
yield break;
}
T firstValue = firstIterator.Current;
T secondValue = secondIterator.Current;
while (true)
{
int comparison = firstValue.CompareTo(secondValue);
if (comparison == 0) // firstValue == secondValue
{
yield return firstValue;
}
else if (comparison < 0) // firstValue < secondValue
{
if (!firstIterator.MoveNext())
{
yield break;
}
firstValue = firstIterator.Current;
}
else // firstValue > secondValue
{
if (!secondIterator.MoveNext())
{
yield break;
}
secondValue = secondIterator.Current;
}
}
}
}
}
(Vous pourriez prendre un IComparer<T>
si vous vouliez plutôt que de s'appuyer sur des T être comparables.)