ilyas varol
ilyas varol

Reputation: 968

how to get specific collection from a collection with linq?

I want to get all Form objects below the root as a list

    public class Root
    {
        public int recordsTotal { get; set; }
        public int recordsFiltered { get; set; }
        public List<Datum> Data { get; set; }
        public int ResultCode { get; set; }
    }

    public class Datum
    {
        public DateTime StartDate { get; set; }
        public DateTime StopDate { get; set; }
        public List<Evaluation> Evaluations { get; set; }
    }

    public class Evaluation
    {
        public string Evaluator { get; set; }
        public string EvaluatorUserId { get; set; }
        public Form Form { get; set; }
        public DateTime EvaluationDate { get; set; }
        public string EvaluationId { get; set; }
    }

I'm trying to get it with linq but haven't succeeded yet

Upvotes: 1

Views: 388

Answers (2)

Roar S.
Roar S.

Reputation: 10829

Short answer based on my understanding of this:

var forms = root.Data
    .SelectMany(datum => datum.Evaluations)
    .Select(evaluation => evaluation.Form)
    .ToList();

Long answer with test

You don't specify class Form, hence I tested with this minimum code:

using System.Collections.Generic;

namespace XUnitTestProject.StackOverflow
{
    public class Root
    {
        public List<Datum> Data { get; set; }
    }

    public class Datum
    {
        public List<Evaluation> Evaluations { get; set; }
    }

    public class Form
    {
        public string Name { get; set; }
    }

    public class Evaluation
    {
        public Form Form { get; set; }
    }
}

And a test class

using System.Collections.Generic;
using System.Linq;
using Xunit;

namespace XUnitTestProject.StackOverflow
{
    public class LinqTests
    {
        [Fact]
        public void Test()
        {
            var forms = CreateValidRoot().Data
                .SelectMany(datum => datum.Evaluations)
                .Select(evaluation => evaluation.Form)
                .ToList();

            Assert.Equal(2, forms.Count);
            Assert.Equal("~form1~", forms[0].Name);
            Assert.Equal("~form2~", forms[1].Name);
        }

        private static Root CreateValidRoot() => new()
        {
            Data = new List<Datum>
            {
                new()
                {
                    Evaluations = new List<Evaluation>
                    {
                        new() {Form = new Form{Name = "~form1~"}}
                    }
                },
                new()
                {
                    Evaluations = new List<Evaluation>
                    {
                        new() {Form = new Form{Name = "~form2~"}}
                    }
                }
            }
        };
    }
}

Upvotes: 4

Белов Борис
Белов Борис

Reputation: 21

Try to reduce your collection:

var forms = root.Data.Aggregate(
new List<Form>(),
(acc, datum) =>
{
    acc.AddRange(datum.Evaluations.Select(x => x.Form));
    return acc;
});

Upvotes: 1

Related Questions