Search code examples
linqcontainswhere-clauseany

selecting items from a list with linq, where items appear in other two lists


i have two lists which contains guids:

    var activeSoftware = channels.ByPath("/software/").Children.Where(c => c.StateProperties.IsActive).Select(c => c.Guid);
    var activeChannels = channels.ByPath("/game-channels/").Children.Where(c => c.StateProperties.IsActive).Select(c => c.Guid);

and another list, of games:

List<MyCms.Content.Games.Game> games = new List<MyCms.Content.Games.Game>();

the game object has two properties that can use:

game.gamingproperties.software - which contains the guid of the software game.stateproperties.channels - a list of comma seperated guids

yes, i know its not good to save comma seperated values in a field, but i cannot change it at this point of time ( its allready working on 40+ sites )

what i want to do, is select all games where the software is active ( by comparing softwarelist to the game.gamingproperties.software ) and that the channels they appear in is active ( by checking if game.stateproperties.channels contains any of activechannels guids )

originally, i have done this like so:

    foreach (var channel in activeSoftware)
    {
        foreach (var match in oGames.AllActive.Where(g => !string.IsNullOrEmpty(g.GamingProperties.UrlDirectGame) && g.GamingProperties.Software.Contains(channel) && g.StateProperties.Channels.Split(',').Intersect(activeChannels).Any()))
        {
            games.Add(match);
        }
    } 

but i am sure i can get rid of those nasty foreach and just use linq.


Solution

  • Your object model does look a little odd, so I think it could be refactored somewhat, but here's my answer:

    var query =
        from channel in activeSoftware
        from match in oGames.AllActive
        where !string.IsNullOrEmpty(match.GamingProperties.UrlDirectGame)
        where match.GamingProperties.Software.Contains(channel)
        where match.StateProperties.Channels.Split(',').Intersect(activeChannels).Any()
        select match;
    
    var games = query.ToList();
    

    You could also do this, if I understand your model correctly:

    var query =
        from match in oGames.AllActive
        where !string.IsNullOrEmpty(match.GamingProperties.UrlDirectGame)
        where match.GamingProperties.Software.Intersect(activeSoftware).Any()
        where match.StateProperties.Channels.Split(',').Intersect(activeChannels).Any()
        select match;
    
    var games = query.ToList();
    

    Hope that helps.