Home > Blockchain >  How to check for each of the items in a list if they are contained in a propery of a class via LINQ
How to check for each of the items in a list if they are contained in a propery of a class via LINQ

Time:09-16

I have an entity Card with a property Title. I also have a field for searching through all the cards' titles with a search term. Let's say that I have card titles 'Dark Magician' and 'Blue Eyed Dragon'. If I search for 'Magician Dragon' I need to receive both the cards, if I search for 'Blue dog with a house' I need to receive the 'Blue Eyed Dragon'card. As of now I have this code, but I can't make up the correct LINQ code.

CardsController.cs, the All view:

public IActionResult All(string searchTerm)
        {
            var cardsQuery = this.data.Cards.AsQueryable();

            if (!string.IsNullOrWhiteSpace(searchTerm))
            {
                //Removing all the white spaces and then joining the different words by a space
                searchTerm = string.Join(" ", searchTerm.Split(default(string[]), StringSplitOptions.RemoveEmptyEntries));

                //Splitting the searchTerm and making it a list of strings
                var searchTermSplitted = searchTerm.Split().ToList();

                //Trying to check if any and which words are contained in any of the cards' titles
                cardsQuery = cardsQuery
                    .Where(c => c.Title.ToLower().Contains(searchTermSplitted)); //Not working, just for the idea
            }

            var cards = cardsQuery
                .OrderByDescending(c => c.Id)
                .Select(c => new CardListingViewModel
                {
                    Title = c.Title,
                    ImageUrl = c.ImageUrl,
                    Category = c.Category.Name,
                    Condition = c.Condition.Name

                })
                .ToList();

            return View(new AllCardsQueryModel
            {
                Cards = cards
            }); ;
        }

CodePudding user response:

Try following :

           List<Card> cards = new List<Card>();

            string searchPattern = "Magician Dragon";
            List<string> searchWords = searchPattern.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries).ToList();

            var results = cards.Where(x => searchWords.Any(y => x.Title.Contains(y)));

CodePudding user response:

So having a search phrase like

  Blue dog with a house

we shoud return all the items which share at least one word with the search phrase. If data.Cards is not that large and we can use AsEnumerable() in order to filter on client:

  string searchTerm = "Blue dog with a house";

  var wordsToFind = new HashSet<string>(
    searchTerm.Split(' ', StringSplitOptions.RemoveEmptyEntries), 
    StringComparer.OrdinalIgnoreCase); 

  var result = data
    .Cards
    .AsEnumerable() // we will sort on the client
    .Where(card => card
       .Title
       .Split(' ')
       .Any(word => words.Contains(word)))
    .Select(c => new CardListingViewModel() {
       Title     = c.Title,
       ImageUrl  = c.ImageUrl,
       Category  = c.Category.Name,
       Condition = c.Condition.Name
     })
    .ToList(); 
  • Related