Intersect LINQ query

后端 未结 7 1923
北恋
北恋 2020-11-30 00:57

If I have an IEnumerable where ClassA exposes an ID property of type long. Is it possible to use a Linq query to get all instances of ClassA with ID belonging to a second IE

相关标签:
7条回答
  • 2020-11-30 01:26

    Naming things is important. Here is an extension method base on the Join operator:

    private static IEnumerable<TSource> IntersectBy<TSource, TKey>(
        this IEnumerable<TSource> source,
        IEnumerable<TKey> keys,
        Func<TSource, TKey> keySelector)
            => source.Join(keys, keySelector, id => id, (o, id) => o);
    

    You can use it like this var result = items.IntersectBy(ids, item => item.id).

    0 讨论(0)
  • 2020-11-30 01:30

    Yes.

    As other people have answered, you can use Where, but it will be extremely inefficient for large sets.

    If performance is a concern, you can call Join:

    var results = original.Join(idsToFind, o => o.Id, id => id, (o, id) => o);
    

    If idsToFind can contain duplicates, you'll need to either call Distinct() on the IDs or on the results or replace Join with GroupJoin (The parameters to GroupJoin would be the same).

    0 讨论(0)
  • 2020-11-30 01:39

    Use the Where method to filter the results:

    var result = original.Where(o => idsToFind.Contains(o.ID));
    
    0 讨论(0)
  • 2020-11-30 01:40

    I've been tripping up all morning on Intersect, and how it doesn't work anymore in core 3, due to it being client side not server side.

    From a list of items pulled from a database, the user can then choose to display them in a way that requires children to attached to that original list to get more information.

    What use to work was:

    itemList = _context.Item
            .Intersect(itemList)
            .Include(i => i.Notes)
            .ToList();
    

    What seems to now work is:

    itemList = _context.Item
            .Where(item => itemList.Contains(item))
            .Include(i => i.Notes)
            .ToList();
    

    This seems to be working as expected, without any significant performance difference, and is really no more complicated than the first.

    0 讨论(0)
  • 2020-11-30 01:41

    A simple way would be:

    IEnumerable<ClassA> result = original.Where(a => idsToFind.contains(a.ID));
    
    0 讨论(0)
  • 2020-11-30 01:46

    You can do it, but in the current form, you'd want to use the Where extension method.

    var results = original.Where(x => yourEnumerable.Contains(x.ID));
    

    Intersect on the other hand will find elements that are in both IEnumerable's. If you are looking for just a list of ID's, you can do the following which takes advantage of Intersect

    var ids = original.Select(x => x.ID).Intersect(yourEnumerable);
    
    0 讨论(0)
提交回复
热议问题