Извлечь элементы IEnumerable <T>, значение ключа которых равно одному из значений ключа в IEnumerable <U> - PullRequest
2 голосов
/ 29 мая 2011

Я хочу извлечь все элементы последовательности IEnumerable, значение ключа которого равно одному из значений ключа в другой последовательности IEnumerable. Пожалуйста, учтите, что первая последовательность имеет тип T, где T:

class T
{
    int SpecificValue;
    // other payload
}

и вторая последовательность имеет тип «U», где U:

class U
{
    int SpecificValueOfSameType;
    // other payload (different from class T)
}

Возможно ли это?

В качестве побочного узла: я использовал термин «Key» -Value, но нет гарантии, что это значение уникально в любой из этих последовательностей. Это должно помочь объяснить мои требования немного подробнее. В реальном коде я могу представить, что есть какой-то параметр Compare-Func).

Ответы [ 4 ]

3 голосов
/ 29 мая 2011

Звучит так, будто вы ищете Join.

ts.Join(us, t => t.SpecificValue, u => u.SpecificValueOfSameType, (t, u) => new Something)
1 голос
/ 29 мая 2011

Как показал К Иванов, вы можете использовать Contains - но если ваша коллекция довольно большая, вам лучше сначала поместить их в HashSet:

var keys = new HashSet<T>(us.Select(u => u.SpecificValueOfSameType));
var query = ts.Where(t => keys.Contains(t.SpecificValue));

РЕДАКТИРОВАТЬ: я упустил тот факт, что в любой коллекции могут быть дубликаты ключей. Это хорошо с приведенным выше кодом, но не будет работать с объединением (по крайней мере, не без вызова Distinct).

Не совсем понятно, что вы подразумеваете под параметром «Compare-Func». Если это просто способ извлечь ключ из последовательности, это нормально. Если это функция для сравнения равенства двух ключей, это другой вопрос. Это значит, что вы не можете иметь в виду хеширование

1 голос
/ 29 мая 2011

попробуйте это:

Ts.Where(t => Us.Select(u => u.SpecificValueOfSameType).Contains(t.SpecificValue))
0 голосов
/ 29 мая 2011

нет никакой гарантии, что это значение уникально в обеих последовательностях.

Это ясно, что вы хотите держаться подальше от большинства объединений.

Как насчет GroupJoin?Этот тип объединения не приводит к дублированию при нескольких совпадениях.

from t in tSource
join u in uSource
  on t.SpecificValue
  equals u.SpecificValueOfSameType
  into g
where g.Any()
select t;

также записывается как:

tSource.GroupJoin(uSource,
  t => t.SpecificValue,
  u => u.SpecificValueOfSameType,
  (t, g) => new {t, g})
.Where(x => x.g.Any())
.Select(x => x.t)
...