Ross
Ross

Reputation: 617

retrieve all fields with same name and type c#

I have a a custom type like the following:

public class Parent
{
    public int Id;
    public List<Child1> C1;
    public List<Child2> C2;

}

public class Child1
{
    public int Id;
}

public class Child2
{
    public int Id;
    public Child3 C3;
}

public class Child3
{
    public int Id;
}

I have a list of the Parent class

List<Parent> parent = new List<Parent>();

What is the best way to get all the Id fields of the 'parent' in a list?

The easiest way would be to use a nested foreach loop but is their a cleaner way of doing it?

I want the Ids of all the Parent Objects as well as the Ids of their recursive Child objects in one List as

List<int> AllIds

Upvotes: 0

Views: 90

Answers (4)

I.G. Pascual
I.G. Pascual

Reputation: 5965

If you want the LINQ solution

List<Parent> parent = new List<Parent>();
var parentIds = parent.
   Select(p => p
       // take C2 ids and C3 ids foreach Parent
      .C2.SelectMany(c2 => new List<string> { c2.Id, c2.C3.Id} )
       // Add each C1 id foreach parent
      .Union(p.C1.Select(c1 => c1.Id))
       // Add its own id
      .Concat(new List<string> { p.id })
   );

Upvotes: 0

Tim Schmelter
Tim Schmelter

Reputation: 460028

You can use SelectMany and Enumerable.Concat:

List<int> allIds = parent
    .SelectMany(p => new[] { p.Id } // or Enumerable.Repeat(p.Id, 1)
        .Concat(p.C1.Select(c => c.Id))
        .Concat(p.C2.Select(c => c.Id)))
    .ToList();

If you instead want to know whether an ID was a child or parent ID you could select an anonymous type which contains the type and it's parent-id if available:

var allIds = parent
    .SelectMany(p => new[] { new { Type="Parent", p.Id, Parent = (int?)null } }
        .Concat(p.C1.Select(c => new { Type = "Child1", c.Id, Parent = (int?)p.Id }))
        .Concat(p.C2.Select(c => new { Type = "Child2", c.Id, Parent = (int?)p.Id })))
    .ToList();

foreach (var x in allIds)
    Console.WriteLine("ID:{0} Type:{1} Parent-ID:{2}", x.Id, x.Type, x.Parent?.ToString() ?? "no parent");

Upvotes: 1

Sean
Sean

Reputation: 62472

You could add an AllIDs property to Parent

public IEnumerable<int> AllIDs
{
  get
  {
    yield return Id;

    foreach(var child in C1)
    {
      yield return child.Id;
    }

    foreach(var child in C2)
    {
      yield return child.Id;
      yield return child.C3.Id;
    }
  }
}

Now you can do a SelectMany on the parent variable

var ids = parent.SelectMany(p => p.AllIDs).ToList();

Upvotes: 2

Barry Gallagher
Barry Gallagher

Reputation: 6246

Get all parent ids:

List<Parent> parents = new List<Parent>();
// populate parent list

int[] parentIds = parents.Select(s => s.Id).ToArray();

Upvotes: -1

Related Questions