2015-11-24 6 views
-1

У меня есть объект, Foo который содержит List<Bar>.Удаление пустого списка объектов из вложенного подсети

Bar содержит List<Baz>.

Baz содержит List<Qux>.

Qux имеет свойство, которое я хочу сравнить.

Если у меня есть List<Foo>, как отфильтровать все Foo объектов из списка, где List<Qux> не заполнен?

EDIT Обновлен мой вопрос, чтобы более адекватно отразить мою проблему.

+0

Если предположить, что 'listFoo' ваш список' Foo' тогда мы имеем 'вар filteredListFoo = listFoo.Select (bar => bar.Select (baz => baz.Select (qux => qux.myproperty == 'somevalue'))) ' –

+0

Ваше правление предполагает, что структура рекурсивна. Это правда? Это поставит вопрос намного легче понять и ответить гораздо проще. – 31eee384

+0

Рекурсивный. – Ian

ответ

0

Спасибо @ 31eee384 за поставив меня на правильный путь.

Я также включил расширение Except(), чтобы удалить пустые списки. Я уверен, что есть более эффективный метод написания этого, поэтому, пожалуйста, напишите, если вы знаете об этом.

Это метод расширения, который я создал.

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(); 
} 
0

Если вы хотите сохранить Foo, когда существует некоторая Qux под ним с определенным значением, сделайте следующее:

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

Если вы хотите сохранить Foo когда все Qux под ним имеют определенное значение, замените Any на All.

+0

Я через ваш код в миксе, и он выпустил те же данные, что и у меня. Я редактировал свой вопрос. – Ian

+0

@Ian Редактированный вопрос не имеет смысла. –

+0

Извините, я в пути. Если List пуст, как отфильтровать этот Baz из списка и то же самое для каждого родителя? – Ian

0

Вы также можете сделать это с более ясным синтаксисом (как для меня в этом случае)

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; 
0
foos.Where(f=>f.Bars.All(bar=>bar.Bazs.All(baz=>baz.Quxs.Any())>)) 

Это должно работать, где каждый baz не будет пустой 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 { } 
+0

Это возвращает список , где List пуст, а не непустым. Список Ian

+0

@ Я знаю, это странно, потому что я получаю две записи, если я запустил этот запрос против этой структуры класса. –

+0

Я заберу его в пятницу, когда я войду в магазин. Мой тест на ваш код был основан на вашем первоначальном ответе .... Оставайтесь с нами! – Ian

Смежные вопросы