Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.73/15: Рейтинг темы: голосов - 15, средняя оценка - 4.73
 Аватар для FastTI
10 / 10 / 7
Регистрация: 29.08.2014
Сообщений: 84

Убрать повторения объекта без использования LINQ

02.11.2016, 16:12. Показов 3252. Ответов 15
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте, подскажите пожалуйста мне как можно убрать повторяющиеся значения в объекте...

к примеру есть список студентов с фамилией, годом рождения, и например факультетом
и я хочу вывести какие факультеты есть из этого списка

при этом чтобы они не повторялись

я написал группировку с помощью LinQ
C#
1
2
3
IEnumerable<int> numOfFacult = from list in listOfStudents
                         group list by list.NumberOfFucult into grp
                         select grp.Key;
теперь сгруппировано факультету и я могу не повторяясь выбрать перечислить информацию....

вопрос как это можно сделать без LinQ?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
02.11.2016, 16:12
Ответы с готовыми решениями:

Linq без использования FrameWork 3.5
Здравствуйте,уважаемые! Я разработал автоматизированную обучающую систему с использованием средств .NET 3.5. Как оказалось позже,внедрять...

Переписать код без использования LINQ to XML
Подскажите пожалуйста аналогичную запись только используя стандартные средства языка C# var dates = from prop in...

без использования invoke (убрать процедуру)
занося параметры функций GetStdHandle и WriteConsoleA в стек без использования процедуры invoke вот прога .386 .model flat,...

15
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
02.11.2016, 16:42
Цитата Сообщение от FastTI Посмотреть сообщение
как это можно сделать без LinQ?
А чем Linq не угодил?

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
static class EnumerableExtensions
{
    public static IEnumerable<T> Distinct<T>(this IEnumerable<T> collection, IEqualityComparer<T> comparer = null)
    {
        if (comparer == null)
            comparer = EqualityComparer<T>.Default;
 
        var hash = new HashSet<T>(comparer);
        foreach (var item in collection)
            if (hash.Add(item))
                yield return item;
    }
    public static IEnumerable<T> Distinct<T, TKey>(this IEnumerable<T> collection, Func<T, TKey> keySelector)
    {
        var hash = new HashSet<TKey>();
        foreach (var item in collection)
        {
            var key = keySelector(item);
            if (hash.Add(key))
                yield return item;
        }                
    }
}
Передавайте в код нужную реализацию IEqualityComparer или делегат с выбором ключа:

C#
1
IEnumerable<int> numOfFacult = listOfStudents.Distinct(s => s.NumberOfFucult);
Добавлено через 6 минут
Заметил, что вы в запросе выбираете ключ группировки.
В таком случае, второй метод можно переписать так:
C#
1
2
3
4
5
6
7
8
9
10
    public static IEnumerable<TKey> Distinct<T, TKey>(this IEnumerable<T> collection, Func<T, TKey> keySelector)
    {
        var hash = new HashSet<TKey>();
        foreach (var item in collection)
        {
            var key = keySelector(item);
            if (hash.Add(key))
                yield return key;
        }
    }
1
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
02.11.2016, 16:45
Цитата Сообщение от FastTI Посмотреть сообщение
вопрос как это можно сделать без LinQ?
Создаешь коллекцию для накопления результата, далее обходишь список и если факультет еще отсутствует в коллекции, добавляешь его туда.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
        static IEnumerable<string> GetDepts(IEnumerable<Student> students)
        {
            var result = new List<string>();
            foreach (Student student in students)
            {
                if (!result.Contains(student.Dept)) result.Add(student.Dept);
            }
            return result;
        }
 
        public class Student
        {
            public string Dept { get; set; }
            public string LastName { get; set; }
            public int BirthYear { get; set; }
 
        }
1
.NET senior
 Аватар для bax_tang
441 / 359 / 137
Регистрация: 23.09.2016
Сообщений: 980
02.11.2016, 20:46
FastTI, вариант с прямым созданием HashSet<string> (на мой взгляд, он самый быстрый):

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Student
{
    public string FirstName, LastName;
    public string Dept;
    public int BirthYear;
 
    // other fields
}
 
public static string[] GetUniqueDepartments(IList<Student> students) // Student[], List<Student>
{
    HashSet<string> deptsSet = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
    
    for (int index = 0; index < students.Count; ++index)
    {
        Student current = students[index];
 
        // return true if dept not exists in set, else otherwise
        deptsSet.Add(current.Dept); 
    }
    
    string[] uniqueDepts = new string[deptsSet.Count];
    deptsSet.CopyTo(uniqueDepts);
    return uniqueDepts;
}
2
 Аватар для FastTI
10 / 10 / 7
Регистрация: 29.08.2014
Сообщений: 84
03.11.2016, 11:06  [ТС]
kolorotur, diadiavova, Спасибо вам за помощь, я воспользуюсь вашими советами...
я не много не понимаю работы IEnumarable<>
diadiavova, ваш пример
C#
1
2
3
4
5
6
7
8
9
 static IEnumerable<string> GetDepts(IEnumerable<Student> students)
        {
            var result = new List<string>();
            foreach (Student student in students)
            {
                if (!result.Contains(student.Dept)) result.Add(student.Dept);
            }
            return result;
        }
можно записать как
C#
1
2
3
4
5
6
7
8
9
10
 static List<int> GetNumOfSchool(List<Students> students)
        {
            var result = new List<int>();
            foreach (Students student in students)
            {
                if (!result.Contains(student.NumberOfSchool))
                    result.Add(student.NumberOfSchool);
            }
            return result;
        }
при этом все отработает ... только студия советует что тип может быть IEnumerable
обязательно использовать этот интерфейс и в чем принципиальная разница в использовании List<int> или IEnumerable<int>...
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
03.11.2016, 11:12
Цитата Сообщение от FastTI Посмотреть сообщение
при этом все отработает
Ну естественно, там же и в самом деле возвращается List.
Цитата Сообщение от FastTI Посмотреть сообщение
обязательно использовать этот интерфейс и в чем принципиальная разница в использовании List<int> или IEnumerable<int>...
Необязательно. Если использовать лист как возвращаемое значение, то, вомзожно, это даже лучше в данном случае. Но IEnumerable<T> - это наиболее общий интерфейс для всех коллекций и в параметрах лучше все-таки использовать именно его, это даст возможность передавать методу коллекцию любого типа, например массив.
1
0 / 0 / 0
Регистрация: 02.11.2016
Сообщений: 1
03.11.2016, 11:21
IEnumerable более "обобщенный"
у List есть методы для обработки кписка
0
 Аватар для FastTI
10 / 10 / 7
Регистрация: 29.08.2014
Сообщений: 84
03.11.2016, 11:40  [ТС]
Цитата Сообщение от diadiavova Посмотреть сообщение
Необязательно. Если использовать лист как возвращаемое значение, то, вомзожно, это даже лучше в данном случае. Но IEnumerable<T> - это наиболее общий интерфейс для всех коллекций и в параметрах лучше все-таки использовать именно его, это даст возможность передавать методу коллекцию любого типа, например массив.
Я вас понял. Спасибо большое
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.11.2016, 12:07
FastTI, на всякий случай: обратите внимание, что в решении, предложенном товарищем diadiavova, при каждой проверке происходит полный обход промежуточного списка, что дает сложность алгоритма O(n2).
Вариант товарища bax_tang работает со сложностью O(2n), т.к. сначала факультеты копируются в хэш, а потом в массив. Мой вариант работает со сложностью O(n).
Вариант товарища bax_tang можно улучшить, если вместо string[] возвращать IEnumerable<string> и отдавать сгенерированный хэшсет, тем самым устраняя копирование всех элементов в массив. Тогда наши алгоритмы будут одинаковы с той разницей, что вариант товарища bax_tang делает полный обход списка в любом случае, а мой вариант выплевывает элементы по-одному, в процессе обхода списка.
Если всегда нужна фильтрация всего списка, то они идентичны, но если нужна только часть (например, если нужны только первые 5 уникальных факультетов), то мой вариант будет эффективнее.
1
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
03.11.2016, 12:32
kolorotur, пара замечаний. Изначально использовать хешсет я не стал из-за того, что вопрос был о реализации алгоритма без использования линк. Причина, по которой было выдвинуто такое условие мне неизвестна и это вполне могла быть необходимость реализации под второй фреймворк, например, в котором никакого хешсета не было и в помине. Нельзя сказать, что там его нечем заменить, поскольку можно, например использовать Dictionary, в котором ключи организованы по тому же принципу, что и хешсет, так что из него вполне себе возможно было соорудить костыль. Но вот о чем я подумал: выигрыш в производительности скорей всего будет незначительным и на малых списках его, скорей всего вообще заметить будет невозможно. Кроме того скорость поиска в коллекциях типа хешсета увеличивается совсем не бесплатно, они организованы по принципу двоичного дерева поиска, а это дерево дает такой эффект только в том случае, если оно сбалансировано. Балансировка дерева - тоже штука не бесплатная. Таким образом, там где обычный список теряет на поиске, хешсеты всякие будут терять на добавлении новых элементов. В результате, если список студентов будет внушительным, а список факультетов получится маленьким, то, очевидно использование хешсета даст вполне диагностируемый прирост производительности, поскольку там будет небольшое количество добавлений, насчет остальных случаев - я совсем не уверен. Ответ может дать только серьезный тест и у меня есть подозрение, что в любом случае это будет "экономия на спичках".
0
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.11.2016, 12:47
Цитата Сообщение от diadiavova Посмотреть сообщение
Причина, по которой было выдвинуто такое условие мне неизвестна и это вполне могла быть необходимость реализации под второй фреймворк
Логично. Кстати, если под второй фреймворк для этого использовать HashTable, то добавится еще и распаковка/запаковка, что само по себе болезненно.

Цитата Сообщение от diadiavova Посмотреть сообщение
выигрыш в производительности скорей всего будет незначительным и на малых списках его, скорей всего вообще заметить будет невозможно.
Согласен, но как про используемый фреймворк, так и про размер списка автор ничего не сказал

Цитата Сообщение от diadiavova Посмотреть сообщение
скорость поиска в коллекциях типа хешсета увеличивается совсем не бесплатно, они организованы по принципу двоичного дерева поиска
Поскольку производительность методов Add и Contains задокументирована как O(1), предположение об использовании двоичного дерева в качестве детали реализации — ошибочно, т.к. поиск и добавление в двоичном дереве — O(log(n)).

Цитата Сообщение от diadiavova Посмотреть сообщение
в любом случае это будет "экономия на спичках"
Не скажите. При более-менее серьезном размере списка разница будет весьма ощутимой.

Разумеется, если метод вызывается раз в год на десяти элементах, то особо мудрить с оптимизациями смысла не имеет.
С другой стороны, разница между использованием списка и хэшсета — ровно одна строчка: заменить new List<string>() на new HashSet<string>(), потому особо не мудрствуя о возможных размерах списка, можно сразу написать "на вырост" и забыть
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
03.11.2016, 13:25
Цитата Сообщение от kolorotur Посмотреть сообщение
Кстати, если под второй фреймворк для этого использовать HashTable
Ну Dictionary во втором уже был, так что такой необходимости точно нет.
Цитата Сообщение от kolorotur Посмотреть сообщение
Согласен, но как про используемый фреймворк, так и про размер списка автор ничего не сказал
Если не считать того, что собираем мы факультеты, а они вряд ли будут тыщами считаться.
Цитата Сообщение от kolorotur Посмотреть сообщение
Поскольку производительность методов Add и Contains задокументирована как O(1), предположение об использовании двоичного дерева в качестве детали реализации — ошибочно
Ну про Add там не совсем так написано, по всей видимости балансировка производится не на каждом добавлении, а только при изменении размера "заначки". Насчет Contains - ничего сказать не могу, видимо это какое-то колдовство )))
Цитата Сообщение от kolorotur Посмотреть сообщение
При более-менее серьезном размере списка разница будет весьма ощутимой.
Уточню: при более-менее серьезном размере списка факультетов.
Цитата Сообщение от kolorotur Посмотреть сообщение
потому особо не мудрствуя о возможных размерах списка, можно сразу написать "на вырост" и забыть
Возможно. В любом случае я написал тот пост не для спора, а просто чтобы объяснить причину такого выбора.
1
Эксперт .NET
 Аватар для kolorotur
17823 / 12973 / 3382
Регистрация: 17.09.2011
Сообщений: 21,261
03.11.2016, 13:38
Цитата Сообщение от diadiavova Посмотреть сообщение
Ну про Add там не совсем так написано
Ну да, там указано, что если требуется расширение пространства, то будет O(n).
В List<T> — то же самое, потому я этот момент "вынес за скобки".

Цитата Сообщение от diadiavova Посмотреть сообщение
по всей видимости балансировка производится не на каждом добавлении
Там не дерево, потому балансировать нечего
HashSet использует хэш-таблицу, где место хранения высчитывается на основании значения метода GetHashCode элемента. Элементы с совпадающими хэшами хранятся в списке, потому сложность поиска будет зависить от качества реализации метода GetHashCode элементов. Если они все будут возвращать один и тот же хэш, то поиск будет O(n), как в обычном массиве, а если в классе реализована идеальная хэш-функция, то поиск будет всегда O(1).

Цитата Сообщение от diadiavova Посмотреть сообщение
Ну Dictionary во втором уже был
Ага, точно. Я почему-то подумал, что генерики только в тройке появились.

Цитата Сообщение от diadiavova Посмотреть сообщение
я написал тот пост не для спора
Да бог с вами, какой спор? Высокоинтеллектуальная научная дискуссия!
1
 Аватар для FastTI
10 / 10 / 7
Регистрация: 29.08.2014
Сообщений: 84
04.11.2016, 18:55  [ТС]
kolorotur, diadiavova, Спасибо вам за подробное обсуждение! Осталось только переварить)

Добавлено через 6 минут
Цитата Сообщение от diadiavova Посмотреть сообщение
Ну про Add там не совсем так написано
Цитата Сообщение от kolorotur Посмотреть сообщение
Ну да, там указано
а о каком "там" говориться в "Высокоинтеллектуальной научной дискуссии?" в каком конкретном источнике об этом можно почитать не подскажите?
0
 Аватар для diadiavova
7259 / 2606 / 744
Регистрация: 11.04.2015
Сообщений: 4,150
Записей в блоге: 43
04.11.2016, 19:01
FastTI, дык kolorotur же ссылки дал на документацию по методам.
0
 Аватар для FastTI
10 / 10 / 7
Регистрация: 29.08.2014
Сообщений: 84
11.11.2016, 21:50  [ТС]
diadiavova, прошу прощения... не увидел
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
11.11.2016, 21:50
Помогаю со студенческими работами здесь

Отслеживание сессии юзера без использования объекта Session
Подскажите как реализовать идентификацию сессии юзера на сервере, без использования объекта Session? Юзер вводит пароль и на сервере в БД...

Как убрать raid с винчестеров без использования биоса
Подскажите пожалуйста как убрать reid с винчестеров без использования биоса.

Как реализовать данный код без использования объекта Vector?
public boolean expand(DefaultMutableTreeNode parent) { DefaultMutableTreeNode flag = (DefaultMutableTreeNode)parent.getFirstChild();...

Удаление реквизита объекта без проверки использования в других объектах
Всем добрый день! Возникла второй раз ситуация, когда я дала имя реквизиту, а это имя используется уже много где. И при попытке...

Запуск экземпляра СОМ объекта с другой машини без использования IIS
В локальной сети 2 машины. На 1-ой установлен СОМ объект (зарегестрирован в dcomcnfg). Как со второй машины получить экземпляр этого...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
16
Ответ Создать тему
Новые блоги и статьи
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
Как дизайн сайта влияет на конверсию: 7 решений, которые реально повышают заявки
Neotwalker 08.03.2026
Многие до сих пор воспринимают дизайн сайта как “красивую оболочку”. На практике всё иначе: дизайн напрямую влияет на то, оставит человек заявку или уйдёт через несколько секунд. Даже если у вас. . .
Модульная разработка через nuget packages
DevAlt 07.03.2026
Сложившийся в . Net-среде способ разработки чаще всего предполагает монорепозиторий в котором находятся все исходники. При создании нового решения, мы просто добавляем нужные проекты и имеем. . .
Модульный подход на примере F#
DevAlt 06.03.2026
В блоге дяди Боба наткнулся на такое определение: В этой книге («Подход, основанный на вариантах использования») Ивар утверждает, что архитектура программного обеспечения — это структуры,. . .
Управление камерой с помощью скрипта OrbitControls.js на Three.js: Вращение, зум и панорамирование
8Observer8 05.03.2026
Содержание блога Финальная демка в браузере работает на Desktop и мобильных браузерах. Итоговый код: orbit-controls-threejs-js. zip. Сканируйте QR-код на мобильном. Вращайте камеру одним пальцем,. . .
SDL3 для Web (WebAssembly): Синхронизация спрайтов SDL3 и тел Box2D
8Observer8 04.03.2026
Содержание блога Финальная демка в браузере. Итоговый код: finish-sync-physics-sprites-sdl3-c. zip На первой гифке отладочные линии отключены, а на второй включены:. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru