powered by simpleCommunicator - 2.0.56     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как выбрать из списка значения только те которые есть в в другом списке?
22 сообщений из 22, страница 1 из 1
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425263
2king2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Как выбрать из "list2" только те значение Id, которых равно list1
Код: 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.
class MyObj
    {
        public virtual string Id { get; set; }
        public virtual decimal Value { get; set; }

        static void Get()
        { 
            var list1 = new List<string> {"5","1","8","10"};

            var list2 = new List<MyObj> 
            { 
                new MyObj 
                { 
                    Id = "1",
                    Value = 30m
                },

                new MyObj 
                { 
                    Id = "8",
                    Value = 40m
                },
            };
        }
    }



Спасибо!
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425295
petalvik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2king2,

Код: c#
1.
list1.Intersect(list2.Select( x => x.Id))
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425355
2king2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petalvik2king2,

Код: c#
1.
list1.Intersect(list2.Select( x => x.Id))



Спасибо, но немного не так нужно. На выходе должен появиться список List<MyObj>
Т.е. если var list1 = new List<string> {"5"," 1 ","8","10"}; я удалю "1", то на выходе должен получиться List<MyObj> содержащий только
Код: c#
1.
2.
3.
4.
5.
new MyObj 
{ 
   Id = "8",
   Value = 40m
}
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425366
2king2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот получился громоздкий код, который выдает то что надо, но хочеться найти более элегантный подход
Код: c#
1.
 var results = list1.Join(list2, l => l, c => c.Id, (l, c) => new MyObj { Id = c.Id, Value = c.Value }).DefaultIfEmpty().ToList();


У кого-нибудь есть мысли на этот счет?
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425407
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
var results = list2.Where(item => list1.Exists(id => id == item.Id)).ToList();


либо снести громоздкость в
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
    public static class ExtensionMethods
    {
        public static List<MyObj> Get(this List<MyObj> items, List<string> ids)
        {
            // здесь может быть "громоздкий", зато более эффективный код
            return items.Where(item => ids.Exists(id => id == item.Id)).ToList();
        }
    }
...
var results = list2.Get(list1);
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425697
2king2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LR,

Спасибо! Вроде не плохо выглядит :)
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425702
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: c#
1.
var results = list2.Join(list1, a => a.Id, b => b, (a, b) => a);



P.S. LR, совет: уходи от реализаций в сторону абстракций.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425746
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ,

Согласен, в данном случае в Join-е есть все необходимое для "элегантного" кода!
Однако же, нужно учесть что Exists традиционно весьма шустр, и в подобной задаче может оказаться более производительным чем Join...

P.S. за совет спасибо, впал в "медитацию" над вопросом "мое мышление больше конкретное или абстрактное?")))
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425773
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRвпал в "медитацию"
Ну впадать не нужно, конечно :) Но от подобных реализаций в методах а-ля List<T> и иже нужно, конечно, избавляться как от сорняка.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425823
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУНо от подобных реализаций в методах а-ля List<T> и иже нужно, конечно, избавляться как от сорняка.
Ну тут я не согласен.
В определенном случае рассматриваемой задачи (элементов в list2 мало, в list1 много) Where-Exists даст лучшую производительность чем Join (в других случаях, конечно, сильно проиграет). Более того, если производительность критична, нет ничего зазорного в том, чтобы отказаться от линкью-методов и прописать свой "громоздкий" метод-расширение.
Другими словами, не бывает общих (абстрактных) лучших решений, зато бывают лучшие конкретные решения (реализации).
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425856
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRWhere-Exists даст лучшую производительность чем Join
Замеры перформанса в студию.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425936
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУЗамеры перформанса в студию.
Пожалуйста
list1.Count=80, list2.Count=4Exists: results.Count=1, Ticks=8595
Join: results.Count=1, Ticks=9551
GetByIds: results.Count=1, Ticks=7056
или
list1.Count=4, list2.Count=73Exists: results.Count=1, Ticks=7729
Join: results.Count=1, Ticks=8557
GetByIds: results.Count=1, Ticks=5824
соответственно при больших количествах Join уверенно опережает
list1.Count=79, list2.Count=81Exists: results.Count=34, Ticks=12335
Join: results.Count=34, Ticks=8531
GetByIds: results.Count=34, Ticks=7928
все более
list1.Count=1275, list2.Count=1278Exists: results.Count=802, Ticks=592922
Join: results.Count=802, Ticks=13432
GetByIds: results.Count=802, Ticks=452105
и более
list1.Count=12607, list2.Count=12671Exists: results.Count=7971, Ticks=49551781
Join: results.Count=7971, Ticks=51876
GetByIds: results.Count=7971, Ticks=39067865
GetByIds - самый простецкий вариант альтернативы методам линкью:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
        public static List<MyObj> GetByIds(this List<MyObj> items, List<string> ids)
        {
             List<MyObj> res = new List<MyObj>();
             foreach (var item in items) {
                foreach (var id in ids) {
                    if (item.Id == id) {
                        res.Add(item);
                        break;
                    }
                }
            }
             return res;
        }
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425968
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRсоответственно при больших количествах Join уверенно опережает

Как-то ты лихо съехал с темы... Кто давеча писал, что

LRWhere-Exists даст лучшую производительность чем Join

LRExists традиционно весьма шустр, и в подобной задаче может оказаться более производительным чем Join...

?

Во-вторых, принято код замеров тоже прикладывать. На будущее.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425988
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
6342Что было понятно и без "замеров" Where-Exists дает лучшую производительность чем Join в очень "узком" случае
list1.Count=63171, list2.Count=4Exists: results.Count=3, Ticks=78330
Join: results.Count=3, Ticks=261978
GetByIds: results.Count=3, Ticks=55179

Но "замеры" показали, что и в таком "узком" случае производительность Join проседает не смертельно, а вот производительность Where-Exists в других случаях проседает таки смертельно... Второе "открытие", это то, что даже достичь производительности Join (в общем случае) прописывая свой "громоздкий метод", пожалуй, очень непросто, т.е. методы линкью достаточно хорошо оптимизированы (и это радует).
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38425992
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУLRсоответственно при больших количествах Join уверенно опережает

Как-то ты лихо съехал с темы... Кто давеча писал, что

LRWhere-Exists даст лучшую производительность чем Join

LRExists традиционно весьма шустр, и в подобной задаче может оказаться более производительным чем Join...

?

Во-вторых, принято код замеров тоже прикладывать. На будущее.

LRВ определенном случае рассматриваемой задачи (элементов в list2 мало, в list1 много) Where-Exists даст лучшую производительность чем Join (в других случаях, конечно, сильно проиграет).
Будьте более внимательны. На будущее.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38426063
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRWhere-Exists дает лучшую производительность чем Join в очень "узком" случае
Этот вывод был сделан только после моего пинка . До этого ты козырял методом Exists как самым быстрым и лучшим. Твои "узкие" случаи на практике идут в топку, т.к. писать "супер быстрый" код для 3 элементов списке - маразм. Если есть возможность использовать Join/GroupJoin - используй его.

LRНо "замеры" показали, что и в таком "узком" случае производительность Join проседает не смертельно
Не смеши мои тапочки. "Смертельность" для 3 элементов в коллекции имеет нулевой смысл даже для того, чтобы об этом думать.

LRа вот производительность Where-Exists в других случаях проседает таки смертельно...
Поэтому прежде чем что-то утверждать, нужно сначала хотя бы проверить.

LRБудьте более внимательны. На будущее.
По делу, как я понимаю, всё?
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38426397
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУ
Теперь понятно, что из этого
LRВ определенном случае рассматриваемой задачи (элементов в list2 мало, в list1 много) Where-Exists даст лучшую производительность чем Join (в других случаях, конечно, сильно проиграет).
сделано это
МСУLRсоответственно при больших количествах Join уверенно опережает

Как-то ты лихо съехал с темы... Кто давеча писал, что

LRWhere-Exists даст лучшую производительность чем Join

вовсе не из-за невнимательности, как можно было бы предположить, а вполне намеренно. Что ж, каждому свое. Но скучное ж это дело.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38426671
Фотография МСУ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRЧто ж, каждому свое. Но скучное ж это дело.
Просто ты несколько раз повторил про какую-то там производительность Exists. Ну на первый раз я промолчал, думаю, не буду влезать в дебаты по экономии спичек на спичечной фабрике, но потом уж прости, но потребовал замеры. Собственно, того и следовало ожидать, Join рулит.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38430542
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
МСУСобственно, того и следовало ожидать, Join рулит.
Собственно, того и следовало ожидать, Join рулит не всегда .

В мсскл применяется один из трех алгоритмов Join - Nested loops, Merge, Hash , в зависимости от ситуации (выбирает оптимизатор или можно указать хинтом).
В linq2obj применяется лишь один - Hash, т.к. нет статистики для выбора Nested loops (количество элементов IEnumerable неизвестно) и нет индексов для Merge.
Но ситуации, где оптимальней Nested loops ("If one join input is small (fewer than 10 rows) and the other join input is fairly large...") или Merge ("If the two join inputs are not small but are sorted on their join column...") могут быть обусловлены самой постановкой задачи. Тогда есть смысл задуматься над реализацией соответствующего алгоритма.

P.S. Where-Exists по сути как раз и есть неким подобием Nested loops, потому и выигрывает на малых количествах outer-списка
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38431191
Фотография Алексей К
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRP.S. Where-Exists по сути как раз и есть неким подобием Nested loops, потому и выигрывает на малых количествах outer-спискаВ базе nested loop обычно идёт в комбинации с index seek .
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38431773
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Алексей КВ базе nested loop обычно идёт в комбинации с index seek .
Ну да, индексов нет, потому и "некое подобие":). Но общая схема отбора подходящих пар такая же "внешний цикл по outer-списку + внутренний по inner-списку", в отличие от схем Merge и Hash (см. например здесь ).

Для случая, когда оба списка уже отсортированы должным образом и достаточно большие, вроде несложно реализовать Merge-алгоритм. Думается, это даст большой выигрыш, т.к. не надо будет тратить память и время на построение хэш-таблиц.
...
Рейтинг: 0 / 0
Как выбрать из списка значения только те которые есть в в другом списке?
    #38431905
Фотография LR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
LRДля случая, когда оба списка уже отсортированы должным образом и достаточно большие, вроде несложно реализовать Merge-алгоритм. Думается, это даст большой выигрыш, т.к. не надо будет тратить память и время на построение хэш-таблиц.Попробовал вот такую реализацию:
Код: 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 static IEnumerable<TResult> JoinSorted<TOuter, TInner, TKey, TResult>(
            this IEnumerable<TOuter> outer,
            IEnumerable<TInner> inner,
            Func<TOuter, TKey> outerKeySelector,
            Func<TInner, TKey> innerKeySelector,
            Func<TOuter, TInner, TResult> resultSelector
            )
        {
            var comparer = Comparer<TKey>.Default;
            using (var outerEnumerator = outer.GetEnumerator())
            using (var innerEnumerator = inner.GetEnumerator()) {
                bool outerCurr = outerEnumerator.MoveNext();
                bool innerCurr = innerEnumerator.MoveNext();
                while (outerCurr && innerCurr) {
                    int cr = comparer.Compare(outerKeySelector(outerEnumerator.Current), innerKeySelector(innerEnumerator.Current));
                    if (cr == 0) {
                        yield return resultSelector(outerEnumerator.Current, innerEnumerator.Current);
                        innerCurr = innerEnumerator.MoveNext();
                    } else if (cr < 0)
                        outerCurr = outerEnumerator.MoveNext();
                    else
                        innerCurr = innerEnumerator.MoveNext();
                }
            }
        }


Оказалось, многое зависит от типа ключа. С типом int выигрыш есть всегда, и существенный, с типом string - только на больших количествах. Но это и понятно, сравнение строк дорогая операция.
...
Рейтинг: 0 / 0
22 сообщений из 22, страница 1 из 1
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как выбрать из списка значения только те которые есть в в другом списке?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]