Looking for an elegant LINQ query, alternative to SelectMany

This is a simple question but I'm struggling to find an elegant solution. Let's say I have a simple data structure, the list of groups of items. Each group has a unique ID and each item has a unique ID, too.

I want to obtain a given item from a given group, if it exists, or null otherwise. I've come up with two implementations, neither of which I really like:

public class Item
{
    public int ItemId;
}

public class Group
{
    public int GroupId;
    public Item[] Items;
}

public static class Test
{
    public static Item GetItemV1(this IEnumerable<Group> groups, int groupId, int itemId)
    {
        return groups.SelectMany(g => g.Items)
            .FirstOrDefault(i => i.ItemId == itemId);
    }

    public static Item GetItemV2(this IEnumerable<Group> groups, int groupId, int itemId)
    {
        var group = groups.FirstOrDefault(g => g.GroupId == groupId);
        if (group != null)
        {
            return group.Items.FirstOrDefault(i => i.ItemId == itemId);
        }
        return null;
    }
}

Can it be done as a one-liner query, yet without redundant iterations of SelectMany?

Jon Skeet
people
quotationmark

Currently your first option doesn't check for the group ID, but that's easily fixed:

return groups.Where(g => g.GroupId == groupId)
             .SelectMany(g => g.Items)
             .FirstOrDefault(i => i.ItemId == itemId);

Or if there's only going to be one group with a given ID, and you want to stop if you've found that group but not found the item:

return groups.Where(g => g.GroupId == groupId)
             .Take(1) // Don't look through other groups after finding one match
             .SelectMany(g => g.Items)
             .FirstOrDefault(i => i.ItemId == itemId);

people

See more on this question at Stackoverflow