Как я могу фильтровать вложенные списки с помощью Linq? - PullRequest
1 голос
/ 23 января 2012

Я использую LINQ на Dictionary<string, IList<ID>>, например:

var searchCategories = new List {"A", "B", "C"};
Result = CategoryMapper.Mapping.Where(
         x => searchCategories.Contains(x.Key)).
         Select(x => new Tuple<string, IList<ID>>(x.Key, x.Value)).ToList();

Это возвращает все идентификаторы, которые находятся либо в категории A, B или C. Однако я хотел бы получить идентификаторы, которые находятся в категории A, B и C.

Мне трудно понять, как это сделать с помощью Linq.

UPDATE

Извините, но мне следовало добавить дополнительную информацию в мой первоначальный пост. Списки в моем словаре выглядят примерно так (здесь я использую только цифры, чтобы сделать это проще):

A: {1, 2, 3}
B: {1,3}
C: {3}

Так что в данном случае я хотел бы получить «3», потому что это единственное число, которое имеет все категории.

Ответы [ 3 ]

1 голос
/ 23 января 2012

Похоже, вы просто пересекаете все списки.Это должно быть просто получить.

var searchCategories = new HashSet<string> { "A", "B", "C" };
var result = CategoryMapper.Mapping
    .Where(map => searchCategories.Contains(map.Key))
    .Select(map => map.Value as IEnumerable<ID>)
    .Aggregate((acc, cur) => acc.Intersect(cur));

Если ваш тип ID не реализует интерфейс IEquatable<ID>, то вам может потребоваться предоставить средство сравнения равенства (которое, я полагаю, у вас есть) для выполнениясравнения.

 ....Aggregate((acc, cur) => acc.Intersect(cur, new YourIdEqualityComparer()));
0 голосов
/ 23 января 2012

Чтобы получить все идентификаторы, для этого идеально подходит метод SelectMany:

var ids = CategoryMapper.Mapping.SelectMany(kv => kv.Value);
0 голосов
/ 23 января 2012

Вы можете попытаться изменить x => searchCategories.Contains(x.Key) на x => searchCategories.All(c => x.Key.Contains(c)), то есть окончательный фрагмент кода должен быть

var searchCategories = new List<string> {"A", "B", "C"};
Result = CategoryMapper.Mapping.Where(
     x => searchCategories.All(c => x.Key.Contains(c))).
     Select(x => new Tuple<string, IList<ID>>(x.Key, x.Value)).ToList();
...