Skip to content

Instantly share code, notes, and snippets.

@schuchard
Last active November 22, 2023 15:28
Show Gist options
  • Star 8 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save schuchard/a60daa25a1840d9371eae023c5be417a to your computer and use it in GitHub Desktop.
Save schuchard/a60daa25a1840d9371eae023c5be417a to your computer and use it in GitHub Desktop.
Recursively filter out objects that are infinitely nested and return an immutable object
// https://stackblitz.com/edit/recursive-filter-prop?file=index.ts
// perf: https://jsbench.me/8cjrlaine7/1
function flatFilter(nestedProp, compareKey, compareId, arr) {
return arr.filter(o => {
const keep = o[compareKey] != compareId;
if (keep && o[nestedProp]) {
o[nestedProp] = flatFilter(nestedProp, compareKey, compareId, o[nestedProp]);
}
return keep;
});
}
const ARRAY = [
{
id: 1,
children: [
{
id: 2,
children: [
{
id: 3,
},
{
id: 4,
},
],
},
{
id: 5,
children: [
{
id: 3,
},
],
},
],
},
];
console.log(JSON.stringify(flatFilter('children', 'id', 3, ARRAY), null, 2));
/* result
[
{
id: 1,
children: [
{
id: 2,
children: [
{
id: 4,
},
],
},
{
id: 5,
children: [],
},
],
},
];
*/
@Jeremy-Glaus
Copy link

Thanks, really helped me! :)

@schuchard
Copy link
Author

@ayappaP
Copy link

ayappaP commented Aug 25, 2021

I used this in my project. Thanks a lot!!

@schuchard
Copy link
Author

@ayappaP 🙌

@Gabrielfrahm
Copy link

BOA MANO VLW

@Sergio-Pedretti
Copy link

Thanks, it helped us a lot!

@schuchard
Copy link
Author

@filip-dot-cube
Copy link

Hi, thanks for the snippet, helped me a lot. Just in case someone was confused just as I was.
This block causes the original array to be mutated.

 if (keep && o[nestedProp]) {
      o[nestedProp] = flatFilter(nestedProp, compareKey, compareId, o[nestedProp]);
    }

So if you want to make it immutable, you should do something like this:

function flatFilter(nestedProp, predicate, arr) {
  return arr.filter(predicate).map(o => {
      if (o[nestedProp]) {
          return {
              ...o,
              [nestedProp]: flatFilter(nestedProp, predicate, o[nestedProp]),
          };
      } else {
          return o;
      }
  });
}

Then use it like this

const flatFiltered = flatFilter(
        'children',
        child => child.id !== 3,
        ARRAY,
    );
    
 console.log(flatFiltered)
    

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment