简体   繁体   中英

Deep Filtering Array of Objects Javascript

We're trying to wrap our heads around this for awhile and can't seem to get what we're looking for. We've attempted many loops and using lodash library to make this possible but no success. We want to loop through the arrays and return any objects and children that have the property checked:true or remove the objects that have checked: false . There are multiple levels deep and we're not able to return what we're looking for

types: [
  {
    name: 'Dresses',
    checked: true,
    collections: [
      {
        name: 'My Collection',
        checked: true,
        variations: [
          { 
            size: 'XXS',
            checked: true

          },
          { 
            size: 'XS',
            checked: false

          }
        ]
      },
      {
        name: 'False Collection',
        checked: false,
        variations: [
          { 
            size: 'XXS',
            checked: false

          },
          { 
            size: 'XS',
            checked: false

          }
        ]
      }
    ]
  },
  {
    name: 'Tops',
    checked: true,
    collections: [
      {
        name: 'Another Collection',
        checked: true,
        variations: [
          { 
            size: 'XXS',
            checked: false

          },
          { 
            size: 'XS',
            checked: true

          }
        ]
      }
    ]
  }
]

Our Expected output that we are trying to generate would be:

types: [
      {
        name: 'Dresses',
        checked: true,
        collections: [
          {
            name: 'My Collection',
            checked: true,
            variations: [
              { 
                size: 'XXS',
                checked: true

              }
            ]
          }
        ]
      },
      {
        name: 'Tops',
        checked: true,
        collections: [
          {
            name: 'Another Collection',
            checked: true,
            variations: [
              { 
                size: 'XS',
                checked: true

              }
            ]
          }
        ]
      }
    ]

Which removes any object with the property checked: false

I usually choose to use Ramda for such problems. (Disclaimer: I'm one of its authors.) With Ramda, you could do it like this:

 const types = [{"checked": true, "collections": [{"checked": true, "name": "My Collection", "variations": [{"checked": true, "size": "XXS"}]}], "name": "Dresses"}, {"checked": true, "collections": [{"checked": true, "name": "Another Collection", "variations": [{"checked": true, "size": "XS"}]}], "name": "Tops"}] const {is, filter, pipe, toPairs, map, fromPairs} = R; const onlyChecked = (obj) => is(Array, obj) ? filter(onlyChecked, obj) : is(Object, obj) ? pipe( toPairs, filter(([key, val]) => val.checked !== false), map(([key, val]) => [key, onlyChecked(val)]), fromPairs )(obj) : obj; console.log(onlyChecked(types)) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.min.js"></script> 

This should be easy to port to lodash, as the key functions such as fromPairs and toPairs are included in both, and Ramda's is(Array) / is(Object) are very similar to lodash's isArray / isObject .

If you are using lodash, I suggest to use filterDeep method from deepdash :

var filtrate = _.filterDeep(types, function(value, key, parent) {
  if (parent.checked) return true;
});

Here is a test for your case

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