2008-09-11 13 views
8

Obtuve una función que devuelve un Collection<string>, y que se llama recursivamente para eventualmente devolver un gran Collection<string>.Fusionando dos Colección <T>

Ahora, me pregunto cuál es el mejor enfoque para fusionar las listas? Collection.CopyTo() solo copia a la cadena [], y usar un loop foreach() parece ser ineficiente. Sin embargo, dado que también quiero filtrar los duplicados, creo que terminaré con un foreach que llama al Contains() en el Collection.

Me pregunto, ¿hay una forma más eficiente de tener una función recursiva que devuelva una lista de cadenas sin duplicados? No tengo que usar un Collection, puede ser prácticamente cualquier tipo de datos adecuado.

Exclusión única, estoy obligado a Visual Studio 2005 y .net 3.0, por lo que no LINQ.

Editar: Para aclarar: La función saca a un usuario de Active Directory, mira los informes directos del usuario y luego observa recursivamente los informes directos de cada usuario. Entonces el resultado final es una lista de todos los usuarios que están en la "cadena de comandos" de un usuario dado. Dado que esto se ejecuta con bastante frecuencia y en este momento toma 20 segundos para algunos usuarios, estoy buscando formas de mejorarlo. El almacenamiento en caché del resultado durante 24 horas también está en mi lista por cierto, pero quiero ver cómo mejorarlo antes de aplicar el almacenamiento en caché.

Respuesta

16

Si está utilizando la Lista <> puede usar .AddRange para agregar una lista a la otra lista.

O puede utilizar el retorno de rendimiento para combinar listas sobre la marcha de esta manera:

public IEnumerable<string> Combine(IEnumerable<string> col1, IEnumerable<string> col2) 
{ 
    foreach(string item in col1) 
     yield return item; 

    foreach(string item in col2) 
     yield return item; 
} 
1

Creo que HashSet<T> es de gran ayuda.

La clase HashSet<T> proporciona operaciones de alto rendimiento. Un conjunto es una colección que no contiene elementos duplicados, y cuyos elementos no están en un orden particular.

Solo agregue elementos y luego use CopyTo.


actualización: HashSet<T> está en .Net 3.5

Tal vez se puede utilizar Dictionary<TKey, TValue>. Establecer una clave duplicada en un diccionario no generará una excepción.

1

Es posible que desee echar un vistazo a Iesi.Collections y Extended Generic Iesi.Collections (debido a que la primera edición se hizo en 1.1 cuando no había genéricos aún).

Extended Iesi tiene una clase ISet que actúa exactamente como un HashSet: impone miembros únicos y no permite duplicados.

Lo ingenioso de Iesi es que ha configurado operadores en lugar de métodos para fusionar colecciones, por lo que puede elegir entre una unión (|), intersección (&), XOR (^), etc.

1

Puedes pasar la colección a tu método por referencia para que solo puedas agregarle elementos, de esa manera no tienes que devolver nada. Esto es lo que podría parecer si lo hicieras en C#.

class Program 
{ 
    static void Main(string[] args) 
    { 
     Collection<string> myitems = new Collection<string>(); 
     myMthod(ref myitems); 
     Console.WriteLine(myitems.Count.ToString()); 
     Console.ReadLine(); 
    } 

    static void myMthod(ref Collection<string> myitems) 
    { 
     myitems.Add("string"); 
     if(myitems.Count <5) 
      myMthod(ref myitems); 
    } 
} 

según lo declarado por @Zooba Pasando por ref no es necesario aquí, si paso por valor también funcionará.

+0

Creo que la advertencia es la función Contiene() que necesito verificar para duplicados, ya que esto tiene que recorrer la lista completa cada vez. Pero pasar como un árbitro podría funcionar para reducir los gastos generales. –

+0

Pasar como ref no hace ninguna diferencia aquí a menos que asigne un nuevo objeto a myitems. Simplemente pasar por valor funcionará (el valor es la referencia al objeto, ref es la referencia a la variable que contiene la referencia al objeto). – Zooba

0

En lo que va fusión:

Me pregunto, ¿hay una manera más eficaz tener una función recursiva que devuelve una lista de cadenas sin duplicados? No tengo que usar una Colección , puede ser prácticamente cualquier tipo de datos adecuado.

Su función reúne un valor de retorno, ¿no? Está dividiendo la lista proporcionada por la mitad, invocando a sí mismo nuevamente (dos veces) y luego fusionando esos resultados.

Durante el paso de fusión, ¿por qué no solo verifica antes de agregar cada cadena al resultado? Si ya está allí, sáltelo.

Suponiendo que está trabajando con listas ordenadas, por supuesto.