Tre opzioni ora - le prime due sono più generali, in quanto non si basano su MillionIntegerList
in fase di ordinamento (che non è stato originariamente specificato). Il terzo è preferibile nel caso in cui il grande elenco sia già ordinato.
Opzione 1
Sì, c'è sicuramente un modo migliore di farlo, utilizzando LINQ:
var common = MillionIntegerList.Intersect(TwoThousandIntegerList).ToList();
Che vi internamente utilizzare un HashSet<int>
costruita attraverso il TwoThousandIntegerList
, poi cercare ogni elemento di MillionIntegerList
all'interno di esso - che sarà molto più efficiente di passare attraverso l'intero TwoThousandIntegerList
ogni volta.
Se desideri solo quelli non-lista nera, è necessario:
var valid = MillionIntegerList.Except(TwoThousandIntegerList).ToList();
Nota che se avete solo bisogno di iterare i risultati una volta, è necessario rimuovere la chiamata ToList
- ho incluso a materializzare i risultati in modo che possano essere esaminati più volte a buon mercato. Se stai semplicemente iterando, il valore di ritorno di Intersect
o Except
sarà solo stream i risultati, rendendolo molto più economico in termini di utilizzo della memoria.
Opzione 2
Se non si vuole fare affidamento sui dettagli di implementazione di LINQ to Objects, ma si vuole ancora un approccio basato su hash:
var hashSet = new HashSet<int>(TwoThousandIntegerList);
hashSet.IntersectWith(MillionIntegerList);
// Now use hashSet
Opzione 3
L'approccio di utilizzare il fatto che la lista grande è ordinata sarebbe sicuramente utile.
Assumendo che non mente l'ordinamento della lista lista nera prima così, si potrebbe scrivere un flusso (e general purpose) implementazione come questo (non testata):
// 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;
}
}
}
}
}
(si potrebbe prendere un IComparer<T>
se voluto invece di fare affidamento sul fatto che T sia paragonabile.)
È una lista ordinata? –
In realtà la lista dei milioni di interi è ordinata, la lista nera non è – theIrishUser
Ma il costo di ordinare la lista nera nulla rispetto al costo di ciò che si vuole fare. – Thomash