2008-09-11 4 views
8

У меня есть функция, которая возвращает Collection<string>, и это называет себя рекурсивно, чтобы в конечном итоге вернуть один большой Collection<string>.Объединение двух коллекций <T>

Теперь, мне просто интересно, что лучший подход для объединения списков? Collection.CopyTo() только копии в строку [], и использование цикла foreach() кажется неэффективным. Тем не менее, поскольку я также хочу отфильтровать дубликаты, я чувствую, что в итоге я получаю foreach, который вызывает Contains() на Collection.

Интересно, есть ли более эффективный способ иметь рекурсивную функцию, которая возвращает список строк без дубликатов? Мне не нужно использовать Collection, это может быть практически любой подходящий тип данных.

Только исключение, я связан с Visual Studio 2005 и .net 3.0, поэтому LINQ.

Редактировать: Чтобы уточнить: функция выводит пользователя из Active Directory, просматривает прямые отчеты пользователя, а затем рекурсивно просматривает прямые отчеты каждого пользователя. Таким образом, конечным результатом является список всех пользователей, которые находятся в «цепочке команд» данного пользователя. Поскольку это выполняется довольно часто и на данный момент занимает 20 секунд для некоторых пользователей, я ищу способы его улучшить. Кэширование результата за 24 часа также входит в мой список, но я хочу посмотреть, как его улучшить, прежде чем применять кеширование.

ответ

16

Если вы используете Список <>, вы можете использовать .AddRange, чтобы добавить один список в другой список.

Или вы можете использовать возврат выход объединить списки на лету, как это:

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

Я думаю, HashSet<T> - отличная помощь.

Класс HashSet<T> обеспечивает высокая производительность. Набор представляет собой коллекцию, которая не содержит дублирующих элементов и элементы которых не имеют особого порядка.

Просто добавьте к нему предметы, а затем используйте CopyTo.


Update: HashSet<T> в .Net 3.5

Может быть, вы можете использовать Dictionary<TKey, TValue>. Установка дублирующего ключа в словарь не приведет к возникновению исключения.

1

Вы можете посмотреть на Iesi.Collections и Extended Generic Iesi.Collections (потому что первое издание было сделано в 1.1, когда было не дженерики все же).

Extended Iesi имеет класс ISet, который действует точно так же, как HashSet: он обеспечивает уникальные элементы и не позволяет дублировать.

Отличительная особенность Iesi заключается в том, что он задал операторы вместо методов для слияния коллекций, поэтому у вас есть выбор между соединением (|), пересечением (&), XOR (^) и т. Д.

1

Можете ли вы передать коллекцию в ваш метод по ссылке, чтобы вы могли просто добавлять к ней предметы, так что вам не нужно ничего возвращать. Это то, на что может показаться, если вы сделали это в 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); 
    } 
} 

Как заявил @Zooba Проходя мимо исх не надо здесь, если передача по значению она также будет работать.

+0

Я думаю, что оговорка - это функция Содержит(), которую мне нужно проверить на наличие дубликатов, так как это должно проходить через весь список каждый раз. Но передача как ref могла бы работать, чтобы уменьшить накладные расходы. – 2008-09-11 09:29:28

0

Насколько сращивание идет:

Интересно, есть более эффективный способ иметь рекурсивную функцию, которая возвращает список строк без дублей? Мне не нужно использовать коллекцию , она может быть практически любым подходящим типом данных.

Ваша функция собирает возвращаемое значение, не так ли? Вы разделяете предоставленный список пополам, снова вызываете self (дважды) и затем объединяете эти результаты.

Во время этапа слияния, почему бы просто не проверить, прежде чем добавить каждую строку в результат? Если он уже существует, пропустите его.

Предполагая, что вы работаете со отсортированными списками, конечно.

Смежные вопросы