Слияние двух коллекций <T> - PullRequest
8 голосов
/ 11 сентября 2008

Я получил функцию, которая возвращает Collection<string> и которая рекурсивно вызывает себя, чтобы в конечном итоге вернуть один большой Collection<string>.

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

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

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

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

Ответы [ 5 ]

16 голосов
/ 11 сентября 2008

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

Или вы можете использовать yield return для объединения списков на лету так:

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 голос
/ 11 сентября 2008

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

1 голос
/ 11 сентября 2008

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

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

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

1 голос
/ 11 сентября 2008

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

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

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


Обновление : HashSet<T> в .Net 3.5

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

0 голосов
/ 11 сентября 2008

Что касается слияния:

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

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

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

Конечно, если вы работаете с отсортированными списками.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...