Curiosamente, si enumerar sobre el diccionario (longitud N) primero y verificar la lista (longitud M) para su inclusión, luego obtiene el rendimiento de O (NM).
Puede construir un HashSet<>
de los identificadores, pero parece redundante ya que ya tenemos un diccionario (previamente codificado) disponible.
Me gustaría iterar primero sobre los identificadores; dado que la búsqueda del diccionario (por clave) es O (1), esto le da un rendimiento de O (M); sin embargo, esto podría significar que no usa LINQ (ya que TryGetValue
no le encantará LINQ (y presentar una tupla es demasiado como el trabajo duro) ...
Dictionary<string, string> getValidIds(
IDictionary<string, string> salesPersons,
IEnumerable<string> ids) {
var result = new Dictionary<string, string>();
string value;
foreach (string key in ids) {
if (salesPersons.TryGetValue(key, out value)) {
result.Add(key, value);
}
}
return result;
}
no me preocupa demasiado que esto es más líneas que la versión de LINQ, elimina un O (N) de la complejidad ...
Editar; el siguiente podría funcionar (no lo he probado), pero creo que es un abuso de LINQ, y ciertamente no se escalará a PLINQ, etc. ... ¡lo uso con extrema precaución! También creo el enfoque foreach
simplemente tiene menos gastos, por lo que será más rápido ... de todos modos:
Dictionary<string, string> getValidIds(
IDictionary<string, string> salesPersons,
IEnumerable<string> ids)
{
string value = null;
return (from key in ids
where salesPersons.TryGetValue(key, out value) // HACK: v. dodgy
select new { key, value })
.ToDictionary(x=>x.key, x=>x.value);
}
Véase mi respuesta para las notas de rendimiento ... –
1, Marc, aunque creo que si usted está preocupado acerca de Potencia con este tipo de cosas que tienes demasiado en la memoria, ya que es! :) –
@Matt ... bueno, tal vez - pero hay un punto donde O (1)/O (N * log (N)) * no es * irrazonable, pero O (N^2) * es * a problema - si eso es 1k, 10k o 100k depende del proceso específico, por supuesto. –