Home > Net >  Filtering nested list is not bringing back the correct result set
Filtering nested list is not bringing back the correct result set

Time:01-20

I currently have a list of skills which looks something like:

var list = new List<Test>
    {
        new Test
        {
            Name = "Some Name",
            Skills = new List<Skill>
            {
                new Skill { SkillName = "Java" },
                new Skill { SkillName = "JavaScript" },
                new Skill { SkillName = "C#" },
                new Skill { SkillName = "CSS" }
            }
        }
    };

Now, I am trying to filter the result by the search term Java for which the code looks something like:

var searchTerm = "Java";
    
var filteredList = list.Where(t => t.Skills.Any(s => s.SkillName.Contains(searchTerm))).ToList();

Here, I would expect the filteredList to contain Java & JavaScript but it's bringing back all the 4 items. Does anyone know where I'm going wrong?

dotnetfiddle

CodePudding user response:

Your query is about retrieving the Test objects where the Skills property contains an item where the skillname contains your search term. Since you return the full Test object, you're seeing the unaltered list.

You need to reassign the nested Skills property to a list with just the terms you looked for.

CodePudding user response:

In your query Where operator applies to the list of tests only. You need something like:

var searchTerm = "Java";
    
var filteredList = list
    .Where(t => t.Skills.Any(s => s.SkillName.Contains(searchTerm)))
    .Select(t => new Test
        {
            Name = t.Name,
            Skills = t.Skills
                .Where(s => s.SkillName.Contains(searchTerm))
                .ToList()
        })
    .ToList();

CodePudding user response:

You need to create a new list to achieve this. You could do this as follows:

var filteredList =
    // where filters down the list to the tests you are interested in(ones containing a skill that has the search term)
    list.Where(t => t.Skills.Any(s => s.SkillName.Contains(searchTerm)))
        // select creates a new list, where each test only has the skills that match the search term
        .Select(t => new Test
                     {
                       Name = t.Name,
                       Skills = t.Skills.Where(s => s.SkillName.Contains(searchTerm)).ToList()
                     })
        .ToList();
  • Related