Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как выбрать из списка значения только те которые есть в в другом списке? / 22 сообщений из 22, страница 1 из 1
12.10.2013, 18:47
    #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
12.10.2013, 20:20
    #38425295
petalvik
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
2king2,

Код: c#
1.
list1.Intersect(list2.Select( x => x.Id))
...
Рейтинг: 0 / 0
12.10.2013, 22:33
    #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
12.10.2013, 22:50
    #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
13.10.2013, 00:10
    #38425407
LR
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
13.10.2013, 15:30
    #38425697
2king2
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LR,

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



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

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

P.S. за совет спасибо, впал в "медитацию" над вопросом "мое мышление больше конкретное или абстрактное?")))
...
Рейтинг: 0 / 0
13.10.2013, 18:01
    #38425773
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LRвпал в "медитацию"
Ну впадать не нужно, конечно :) Но от подобных реализаций в методах а-ля List<T> и иже нужно, конечно, избавляться как от сорняка.
...
Рейтинг: 0 / 0
13.10.2013, 19:38
    #38425823
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
МСУНо от подобных реализаций в методах а-ля List<T> и иже нужно, конечно, избавляться как от сорняка.
Ну тут я не согласен.
В определенном случае рассматриваемой задачи (элементов в list2 мало, в list1 много) Where-Exists даст лучшую производительность чем Join (в других случаях, конечно, сильно проиграет). Более того, если производительность критична, нет ничего зазорного в том, чтобы отказаться от линкью-методов и прописать свой "громоздкий" метод-расширение.
Другими словами, не бывает общих (абстрактных) лучших решений, зато бывают лучшие конкретные решения (реализации).
...
Рейтинг: 0 / 0
13.10.2013, 20:45
    #38425856
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LRWhere-Exists даст лучшую производительность чем Join
Замеры перформанса в студию.
...
Рейтинг: 0 / 0
13.10.2013, 23:33
    #38425936
LR
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
14.10.2013, 00:05
    #38425968
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LRсоответственно при больших количествах Join уверенно опережает

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

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

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

?

Во-вторых, принято код замеров тоже прикладывать. На будущее.
...
Рейтинг: 0 / 0
14.10.2013, 00:34
    #38425988
LR
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
14.10.2013, 00:38
    #38425992
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
МСУLRсоответственно при больших количествах Join уверенно опережает

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

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

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

?

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

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

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

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

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

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

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

вовсе не из-за невнимательности, как можно было бы предположить, а вполне намеренно. Что ж, каждому свое. Но скучное ж это дело.
...
Рейтинг: 0 / 0
14.10.2013, 14:33
    #38426671
МСУ
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LRЧто ж, каждому свое. Но скучное ж это дело.
Просто ты несколько раз повторил про какую-то там производительность Exists. Ну на первый раз я промолчал, думаю, не буду влезать в дебаты по экономии спичек на спичечной фабрике, но потом уж прости, но потребовал замеры. Собственно, того и следовало ожидать, Join рулит.
...
Рейтинг: 0 / 0
17.10.2013, 01:38
    #38430542
LR
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
17.10.2013, 13:41
    #38431191
Алексей К
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
LRP.S. Where-Exists по сути как раз и есть неким подобием Nested loops, потому и выигрывает на малых количествах outer-спискаВ базе nested loop обычно идёт в комбинации с index seek .
...
Рейтинг: 0 / 0
17.10.2013, 18:26
    #38431773
LR
LR
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Как выбрать из списка значения только те которые есть в в другом списке?
Алексей КВ базе nested loop обычно идёт в комбинации с index seek .
Ну да, индексов нет, потому и "некое подобие":). Но общая схема отбора подходящих пар такая же "внешний цикл по outer-списку + внутренний по inner-списку", в отличие от схем Merge и Hash (см. например здесь ).

Для случая, когда оба списка уже отсортированы должным образом и достаточно большие, вроде несложно реализовать Merge-алгоритм. Думается, это даст большой выигрыш, т.к. не надо будет тратить память и время на построение хэш-таблиц.
...
Рейтинг: 0 / 0
17.10.2013, 20:28
    #38431905
LR
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
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Как выбрать из списка значения только те которые есть в в другом списке? / 22 сообщений из 22, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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