YuriGor / deepdash

eachDeep, filterDeep, findDeep, someDeep, omitDeep, pickDeep, keysDeep etc.. Tree traversal library written in Underscore/Lodash fashion
https://deepdash.io/
MIT License
272 stars 12 forks source link

Option to skip iterating array in filterDeep #82

Closed mtrunt closed 3 years ago

mtrunt commented 3 years ago

Currently using filterDeep you can remove objects based on some condition. However when an array meets those conditions, its children are still iterated even if skipChildren is true and the array ends in the resulting object if any of the children meets the condition.

It would be useful to either have an option to avoid/stop this iteration or that skipChildren would also skip iterating arrays.

Here's an example using the same objects as the docs with some added properties to show the use case.

let things = {
    things: [
      { name: 'something', good: false },
      {
        name: 'another thing', good: true,
        children: [
          { name: 'child thing 1', good: false },
          { name: 'child thing 2', good: true },
          { name: 'child thing 3', good: false },
        ],
      },
      {
        name: 'something else', good: true,
        badChildren: [
          { name: 'bad child thing 1', good: true },
          { name: 'bad child thing 2', good: true },
          { name: 'bad child thing 3', good: false },
        ],
        subItem: { name: 'sub-item', good: false },
        subItem2: { name: 'sub-item-2', good: true },
      },
    ],
  };
  let filtrate = filterDeep(
    things,
    (value, key, parent) => {
      if (key === 'badChildren') return false;
      if (key == 'name' && parent.good) return true;
      if (key == 'good' && value == true) return true;
    }
  );

The resulting object has the badChildren array with [{ name: 'bad child thing 1', good: true }, { name: 'bad child thing 2', good: true }] since they matched the good == true condition.

The expected object would have completely removed the badChildren array without even iterating its elements.

Or is there a better way of accomplishing this?

YuriGor commented 3 years ago

Hi, take into account leavesOnly option is true by default, so this condition

if (key === 'badChildren') return false;

is never tested in your example.

Here is a demo for your case: https://codepen.io/yurigor/pen/WNGEJeN?editors=0010 let me know if this is what are you looking for.

mtrunt commented 3 years ago

Ah, that solves it! I was playing with the options but couldn't get it to work properly.

Thanks!