2

I've been scouring multiple resources and can't figure this one out; I am trying to filter an Array of objects based on a Property that is nested a couple levels deep. I've simplified things, so let's say I have the following classes:

class A {
  B[] bb;
}

class B 
  C[] cc;
}

class C {
  string value;
}

And now the code:

A[] aa = ...;
A[] filteredAa = aa.Where(... //NEED HELP HERE

What I want to do is filter the aa array such that it gives me only those A elements that have at least one B element that have at least one C element has a value of "hello" (e.g. aa[0] would be included in the filteredAa array if aa[0].bb[3].cc[2].value = "hello").

Can this type of filtering even be done? I think and hope this makes sense, but please let me know if I can clarify any further.

2
  • whats the issue? no results? an error? only one result where there should be 20? Commented Jan 21, 2013 at 16:29
  • Sorry, I removed my code sample from my question because it actually wasn't working at all. Howie got it though! Commented Jan 21, 2013 at 16:43

4 Answers 4

4

You need to use Any - and it sounds like you need to use it twice:

var query = aa.Where(a => a.bb.Any(b => b.cc.Any(c => c.value == "hello")));

So working up from the inside:

  • A C object is useful if its value is "hello"
  • A B object is useful if any of its C values are useful
  • An A object is useful if any of its B values are useful
  • Where filters a sequence of A objects, leaving only the useful ones

You can use ToArray() at the end if you really want an array, but I would typically use ToList or just keep it as an IEnumerable<A>.

Sign up to request clarification or add additional context in comments.

7 Comments

Great explanation, really puts the Any() method into context - didn't realize it was so easy.
how can I get value combined from A & C like ....Select(d => new {a.A, c.C})
@SZT: I'd need to know the exact details; it doesn't sound like it's really a very good fit for this question which is more about existence than projecting. I suggest you ask a new question with all the relevant details and a minimal reproducible example.
@JonSkeet could you take a look at this: stackoverflow.com/q/69828436/713847
@SZT: Given that you're using LINQ to SQL, the answer will depend on knowing what that supports; it's been years since I've used it I'm afraid.
|
1

Try this:

A[] filteredAa = aa.Where(a => a.bb.Any(b => b.cc.Any(c => c.value == "hello"))).ToArray();

Comments

0

If you are looking for where Value is a specific value:

var result = aa.Where(a=>a.bb.Any(b => b.cc.Any(c => c.Value == "hello"));

If you just want to get all of those that have any value:

var result = aa.Where(a=>a.bb.Any(b => b.cc.Any(c => !string.IsNullOrEmpty(c.Value)));

1 Comment

+1 i liked this because it used where its not null rather than hello, as his initial (unedited) question asked for results where value existed rather than where value was hello
0
filteredAa = aa.Where(x => x.bb.Any(y => y.cc.Any(z => z.value == "hello")))

1 Comment

I am so sorry, It's too late, but next time, i'll do it;)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.