Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. LINQ
  4. Filtering Sublist

Filtering Sublist

Scheduled Pinned Locked Moved LINQ
csharplinqquestion
6 Posts 2 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • M Offline
    M Offline
    MBursill
    wrote on last edited by
    #1

    You have a list of items (Item type A). For each item in that list, you have a sub-list of items (Item type B). You have another independent list of type B. You wish to filter the first list to only contain the items (and sub-items) in your independent list of type B's. You're using C# and LINQ. How the heck do you do it? -Mike.

    E 1 Reply Last reply
    0
    • M MBursill

      You have a list of items (Item type A). For each item in that list, you have a sub-list of items (Item type B). You have another independent list of type B. You wish to filter the first list to only contain the items (and sub-items) in your independent list of type B's. You're using C# and LINQ. How the heck do you do it? -Mike.

      E Offline
      E Offline
      Eslam Afifi
      wrote on last edited by
      #2

      var aList = new List<A>();
      var filterList = new List<B>();

      var res1 = from a in aList
      where a.BList.Any(b => filterList.Contains(b))
      select a;
      // or
      var res2 = from a in aList
      where a.BList.All(b => filterList.Contains(b))
      select a;
      // depending on your filtering criteria.

      For the classes,

      class A
      {
      public List<B> BList;
      }

      class B
      {
      }

      Eslam Afifi

      M 1 Reply Last reply
      0
      • E Eslam Afifi

        var aList = new List<A>();
        var filterList = new List<B>();

        var res1 = from a in aList
        where a.BList.Any(b => filterList.Contains(b))
        select a;
        // or
        var res2 = from a in aList
        where a.BList.All(b => filterList.Contains(b))
        select a;
        // depending on your filtering criteria.

        For the classes,

        class A
        {
        public List<B> BList;
        }

        class B
        {
        }

        Eslam Afifi

        M Offline
        M Offline
        MBursill
        wrote on last edited by
        #3

        Thanks for the reply. This is close to what I want, but not exactly. The filtering is taking place on A, but not also B. Perhaps an example would help: Lets say List A was called AlphabetList, and had the letters A through Z, each as an object (an item to the list). Now lets say List B was called NumbersList and each instance contained five numbers. For every AlphabetList there is a NumbersList. The sets might look like this: A (1,2,3,4,5) B (6,7,8,9,10) C (11,12,13,14,15) ... if my independent NumbersList contained (7, 14), I'm looking for a LINQ statement which could filter the AlphabetList to contain only the objects marked B and C, and within those, filter the NumbersList items to only contain the objects with the numbers 7 and 14. Thanks. -Mike.

        E 1 Reply Last reply
        0
        • M MBursill

          Thanks for the reply. This is close to what I want, but not exactly. The filtering is taking place on A, but not also B. Perhaps an example would help: Lets say List A was called AlphabetList, and had the letters A through Z, each as an object (an item to the list). Now lets say List B was called NumbersList and each instance contained five numbers. For every AlphabetList there is a NumbersList. The sets might look like this: A (1,2,3,4,5) B (6,7,8,9,10) C (11,12,13,14,15) ... if my independent NumbersList contained (7, 14), I'm looking for a LINQ statement which could filter the AlphabetList to contain only the objects marked B and C, and within those, filter the NumbersList items to only contain the objects with the numbers 7 and 14. Thanks. -Mike.

          E Offline
          E Offline
          Eslam Afifi
          wrote on last edited by
          #4

          You're welcome :) So you want something like this?

          var res1 = from a in aList
          let matchedInA = a.BList.Intersect(filterList)
          where matchedInA.Count() != 0
          select new { a, matchedInA };

          I didn't test the code.

          Eslam Afifi

          M 1 Reply Last reply
          0
          • E Eslam Afifi

            You're welcome :) So you want something like this?

            var res1 = from a in aList
            let matchedInA = a.BList.Intersect(filterList)
            where matchedInA.Count() != 0
            select new { a, matchedInA };

            I didn't test the code.

            Eslam Afifi

            M Offline
            M Offline
            MBursill
            wrote on last edited by
            #5

            That works, however, I was hoping for a way that didn't return an anonymous type. I wanted to keep the original object containment. The now filtered list of B's still kept inside the respective A's. Starting to think LINQ might not be able to do that. It's a puzzler. :confused: -Mike.

            E 1 Reply Last reply
            0
            • M MBursill

              That works, however, I was hoping for a way that didn't return an anonymous type. I wanted to keep the original object containment. The now filtered list of B's still kept inside the respective A's. Starting to think LINQ might not be able to do that. It's a puzzler. :confused: -Mike.

              E Offline
              E Offline
              Eslam Afifi
              wrote on last edited by
              #6

              You can iterate over the result returned from the query and modify the original collection. I've just had a crazy idea to do it all in the query and I don't know if it will work or not but here it is anyway.

              var res1 = from a in aList
              let bListOriginalCount = a.BList.Count
              let removedCount = a.BList.RemoveAll(b => !filterList.Contains(b))
              where removedCount == bListOriginalCount
              select a; // will affect ALL items in aList
              // or
              var res1 = from a in aList
              let removedCount = a.BList.RemoveAll(b => !filterList.Contains(b))
              where a.BList.Count != 0
              select a; // will affect ALL items in aList
              // or
              var res1 = from a in aList
              let matchedInA = a.BList.Intersect(filterList)
              where matchedInA.Count() != 0
              let dummyA = ((Func<A>)(() =>
              {
              a.BList.RemoveAll(b => !matchedInA.Contains(b));
              return a;
              })).Invoke()
              select dummyA; // will affect only matched items in aList

              And you can do it with normal loops. LINQ is puzzler at the begining but with time you will find it easy. It's just some extension methods (static methods over IEnumerable...), lambda expressions (anonymous methods) and relational algebra (kinda) :cool: Please let me know which works and which doesn't.

              Eslam Afifi

              1 Reply Last reply
              0
              Reply
              • Reply as topic
              Log in to reply
              • Oldest to Newest
              • Newest to Oldest
              • Most Votes


              • Login

              • Don't have an account? Register

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • World
              • Users
              • Groups