simbada
simbada

Reputation: 980

Linq to filter nested list

Ok, I wrote below LINQ to Entities query (close enough to my c# query showing below)

var itemss = filteredstudents
.Where(x => x.SubjectTypes.Any(y => y.SubjectItem.Any(z => z.Name  == value1))).ToList();

still little problem because when SubjectItem type has two element and one of them match with value1. it still returns both. It should return only matching record. I know the problem is with Any but not sure Any to replace with what?

foreach (StudentDTO student in filteredstudents)
{
    bool valid = true;
    foreach (SubjectTypes subjectType in student.SubjectTypes)
    {
        string value1 = subjectType.SubjectItem.Select(x => x.value1).First();
        Guid StId = _context.Items.Where(x => x.Name == value1).FirstOrDefault();

        if (StId != null)
            valid = true;
        else
        {
            valid = false;
            _log("create log");
        }
    }
    if (valid)
        filteredstudentsWithUnits.Add(student);
}

Sample Input

{"Name":"ABC",
"Age":12,
,"SubjectTypes":
[
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"bbb"}]}
]
}

Expected Output

{"Name":"ABC",
"Age":12,
,"SubjectTypes":
[
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},
{"Id":"1","Description":""Description","SubjectItem":[{"Id":"1","Marks":12,"Name":"aaa"}]},

]
}

Upvotes: 4

Views: 10206

Answers (3)

Srini V
Srini V

Reputation: 65

The below logic might help you to filter only nested list.

For ex:

Consider below class structure:

class EntityName { int i; string xx; List<SubEntity> subEntityName; }

Then, filter only the subEntity details like this.

objEntity.SubEntityName = objEntity.SubEntityName.Where(x=>x.attrubute== "")"

Upvotes: 0

Jaime Macias
Jaime Macias

Reputation: 847

This will solve your issue but there may be better ways of doing it, also I omitted some properties like the Ids and marks that you'll need to add.

var items = filteredstudents.Select(s => new StudentDTO
{
    Name = s.Name,
    SubjectTypes = s.SubjectTypes.Select(st => new SubjectType
    {
        Description = st.Description,
        SubjectItems = st.SubjectItems.Where(si => si.Name == "AAA").ToList()
    }).Where(x => x.SubjectItems.Count > 0).ToList()
});

Upvotes: 1

Neil Mountford
Neil Mountford

Reputation: 2001

You could filter the list first using .Where and then use .Select to project to a new collection that contains only the data you want. Something like the following may work:

var itemss = filteredstudents
    .Where(s => s.SubjectTypes.Any(st => st.SubjectItem.Any(si => si.Name  == value1)))
    .Select(s => new StudentDTO
    {
        Name = s.Name,
        Age = s.Age,
        SubjectTypes = s.SubjectTypes.Where(st => st.SubjectItem.Any(si => si.Name  == value1))
            .Select(st => new SubjectType
            {
                Id = st.Id,
                Description = st.Description,
                SubjectItem = st.SubjectItem.Where(si => si.Name == value1).ToList()
            }).ToList()
    })
    .ToList();

Upvotes: 4

Related Questions