How to join the two lists?

(The full code is available at: https://dotnetfiddle.net/tdKNgH )

I have two lists that are related to ParentName, and I would like to join them in a certain way.

class Parent
{
    public string ParentName { get; set; }
    public IEnumerable<string> ChildNames { get; set; }
}

class Child
{
    public string ParentName { get; set; }
    public string ChildName { get; set; }
}

var parents = new List<Parent>()
{
    new Parent() {ParentName = "Lee"},
    new Parent() {ParentName = "Bob"},
    new Parent() {ParentName = "Tom"}
};

var children = new List<Child>()
{
    new Child() {ParentName = "Lee", ChildName = "A"},
    new Child() {ParentName = "Tom", ChildName = "B"},
    new Child() {ParentName = "Tom", ChildName = "C"}
};

I use the foreach loop to connect and it works, but is there a more concise way to do this?

foreach (var parent in parents)
{
    var p = parent; // to avoid foreach closure side-effects
    p.ChildNames = children.Where(c => c.ParentName == p.ParentName)
                           .Select(c => c.ChildName);
}

The list of recipients will look here:

Parent Children
------ --------
Lee    A 
Bob    (empty) 
Tom    B,C
+4
source share
5 answers

You can use ToLookup for better performance with a small memory penalty:

 var clu = children.ToLookup(x => x.ParentName, x => x.ChildName);
 parents.ForEach(p => p.ChildNames = clu[p.ParentName]);
+1
source

You can add an extension method for enumerations:

public static void Each<T>(this IEnumerable<T> source, Action<T> action)
{
    if (action == null)
        return;
    foreach (T obj in source)
        action(obj);
}

And then do:

parents.Each(p => p.ChildNames = children.Where(c => c.ParentName == p.ParentName)
                                         .Select(c => c.ChildName));
+1
source

. LINQ . , .

IEnumerable<Parent> parents = ...;

var parentsWithChildren = parents.GroupJoin(children,
                                            c => c.ParentName,
                                            c => c.ParentName,
                                            (a, b) => new
                                                      {
                                                          Parent = a,
                                                          ChildNames = b.Select(x => x.ChildName)
                                                      });

foreach (var v in parentsWithChildren)
{
    v.Parent.ChildNames = v.ChildNames;
}

, , , , , , Parent, , type ((a, b) => new { ... }). , Parent , , , .

+1

Parent.Name Parent.ParentName ( ?), Child ...

class Parent
{
    public string Name { get; set; }
    public IEnumerable<string> ChildrenNames { get; set; }
}

class Child
{
    public string ParentName { get; set; }
    public string Name { get; set; }
}

foreach, parentNames:

var parentNames = new[] { "Lee", "Bob", "Tom" };
var allChildren = new List<Child>()
{
    new Child() {ParentName = "Lee", Name = "A"},
    new Child() {ParentName = "Tom", Name = "B"},
    new Child() {ParentName = "Tom", Name = "C"}
};

, LINQ - ( ), :

var parents =
    from parentName in parentNames
    join child in allChildren on parentName equals child.ParentName into children
    select new Parent { Name = parentName, ChildrenNames = children.Select(c => c.Name) };
+1

, LINQ , , , - ( , foreach).

:

var parents = new List<Parent>()
{
    new Parent() { ParentName = "Lee" },
    new Parent() { ParentName = "Bob" },
    new Parent() { ParentName = "Tom" }
};

var children = new List<Child>()
{
    new Child() { ParentName = "Lee", ChildName = "A" },
    new Child() { ParentName = "Tom", ChildName = "B" },
    new Child() { ParentName = "Tom", ChildName = "C" }
};

var parentsWithChildren = parents.Select(x => new Parent 
{ 
    ParentName = x.ParentName, 
    ChildNames = children
        .Where(c => c.ParentName == x.ParentName)
        .Select(c => c.ChildName) 
});

foreach (var parent in parentsWithChildren)
{
    var childNamesConcentrated = string.Join(",", parent.ChildNames);

    var childNames = string.IsNullOrWhiteSpace(childNamesConcentrated) 
        ? "(empty)" : childNamesConcentrated;

    Console.WriteLine("Parent = {0}, Children = {1}", parent.ParentName, childNames);
}

Parent parents, ChildNames. Parent .

+1

All Articles