简体   繁体   中英

Removing an empty list of objects from a nested sublist

I have an object, Foo which contains a List<Bar> .

Bar contains a List<Baz> .

Baz contains a List<Qux> .

Qux has a property I want to compare.

If I have List<Foo> , how do I filter out all Foo objects from the list where List<Qux> is empty?

EDIT Updated my question to more appropriately reflect my problem.

If you want to keep a Foo when there exists some Qux under it with a certain value, do this:

List<Foo> foos = ...;
IEnumerable<Foo> query = foos
    .Where(foo => foo.Bars
        .SelectMany(bar => bar.Bazs)
        .SelectMany(baz => baz.Quxs)
        .Any(qux => qux.SomeProperty == someValue));

If you want to keep a Foo when all Qux under it have a certain value, replace Any with All .

You can also do this with more clear syntax (like for me in that case)

List<Foo> lst = GetFooList();
var foos = from foo in lst
           from bar in foo.Bars
           from baz in bar.Bazs
           from qux in baz.Quxs
           where qux.Property != somevalue
           select foo;

Thanks @31eee384 for putting me on the right track.

I also incorporated the Except() extension to remove the empty lists. I'm sure there is a more efficient method of writing this, so, please post if you know of one.

This is the extension method that I created.

internal static List<Foo> OnlyWithQuxs(this List<Foo> model)
{
    var foosToRemove = new List<Foo>();

    foreach (var foo in model)
    {
        var barsToRemove = new List<Bar>();

        foreach (var bar in foo.bars)
        {
            var bazWithQux = new List<Baz>();
            var bazsToRemove = new List<Baz>();

            foreach (var baz in bar.bazs)
            {

                baz.Quxs = GetbazQuxs(baz.Id)
                    .Where(qux => qux.Property == someValue)
                    .ToList();

                bazWithQux.Add(baz);

                if (baz.Quxs == null || baz.Quxs.Count() == 0)
                    bazsToRemove.Add(baz);
            }

            bar.bazs = bazWithQux.Except(bazsToRemove).ToList();

            if (bar.bazs == null || bar.bazs.Count() == 0)
                barsToRemove.Add(bar);
        }

        foo.bars = foo.bars.Except(barsToRemove).ToList();

        if (foo.bars == null || foo.bars.Count() == 0)
            foosToRemove.Add(foo);
    }

    return model.Except(foosToRemove).ToList();
}
foos.Where(f=>f.Bars.All(bar=>bar.Bazs.All(baz=>baz.Quxs.Any())>))

This should work where every baz will not have an empty List<Qux>

var foos = new List<Foo>
            {
                new Foo {Bars = new List<Bar> {new Bar { Bazs = new List<Baz> { new Baz { Quxs = new List<Qux> { new Qux()} } } } } },
                new Foo {Bars = new List<Bar> {new Bar { Bazs = new List<Baz> { new Baz { Quxs = new List<Qux> { new Qux()} } } } } },
                 new Foo {Bars = new List<Bar> {new Bar { Bazs = new List<Baz> { new Baz { Quxs = new List<Qux> { } } } } } },

            };

            var r = foos.Where(f => f.Bars.All(bars=>bars.Bazs.All(baz=>baz.Quxs.Any()))).ToList();

 class Foo
{
    public List<Bar> Bars { get; set; }
}

class Bar
{
    public List<Baz> Bazs { get; set; }
}

class Baz
{
    public List<Qux> Quxs { get; set; }
}

class Qux { }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM