YuriGor / deepdash

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

Support pickByDeep, OmitByDeep #50

Closed GaborTorma closed 4 years ago

GaborTorma commented 4 years ago

Based on: https://lodash.com/docs/4.17.15#pickBy https://lodash.com/docs/4.17.15#omitBy

Thanx!

YuriGor commented 4 years ago

Hi, @GaborTorma, thank you for attention!

Do you expect any difference between pickByDeep and filterDeep? (and same for omitByDeep vs filterDeep with reversed criteria in predicate?)

GaborTorma commented 4 years ago

Sorry, no differences. Lodash results only array and cut the key. Your solution is good. I close this issue.

YuriGor commented 4 years ago

Yeah, filtering deep object in a Lodash way makes not so much sense, but name filterDeep maybe is confusing for those who expect more similarity with lodash. I'll think about adding aliases.

GaborTorma commented 4 years ago

I made the pickByDeep: _.pickByDeep = (obj, predicate, options) => { const result = _.isArray(obj) ? [] : {} _.eachDeep( obj, (v, k, p, c) => { if (predicate(v, k, p, c)) { _.set(result, c.path, v) } }, options ) return result }

You can check the differences in the following: https://codepen.io/gabortorma/pen/LYpJyjd

The filterDeep not able to use in nested object property, because it's removed in parent level. Maybe it works for omit with !predicate. I not tested it.

GaborTorma commented 4 years ago

My first version with reduce: function pickByDeep(obj, predicate, options) { return _.pick( obj, _.reduceDeep( obj, (r, v, k, p, c) => { if (predicate(v, k, p, c)) { r.push(c.path) } return r }, [], options ) ) }

But I think the eachDeep is quicker.

YuriGor commented 4 years ago

Hi, here is a config for filterDeep to behave as you need: https://codepen.io/yurigor/pen/oNjPWOQ Also notice i changed predicate a bit, because deepdash expect 3 possible responses from predicate, true, false and undefined (in general it means yes, no and not sure)

GaborTorma commented 4 years ago

Ohh, i didn't know the undefined predictive result... Thanx! Maybe can you provide omitByDeep with filterDeep?

Expected result with same predicate: [ { "name": "grand 2", "children": { "c2": { "name": "parent 2.2", "children": [ { "name": "child 2.2.1" }, { "name": "child 2.2.2" } ], }, } }, { "name": "grand 2", "children": { "c1": { "name": "nincs", "valami": 111, "children": [ { "name": "child 2.1.1" }, { "name": "child 2.1.2" } ] }, "c2": { "name": "parent 2.2", "children": [ { "name": "child 2.2.1" }, { "name": "child 2.2.2" } ], }, } } ] ;

GaborTorma commented 4 years ago

My solution of omitByDeep: omitByDeep = (obj, predicate, options) => { const result = _.cloneDeep(obj) _.eachDeep( obj, (v, k, p, c) => { if (predicate(v, k, p, c)) { _.unset(result, c.path) } }, options ) return result }

YuriGor commented 4 years ago

Could you please also create codepen, same as you did for pickByDeep so I'll fork it and suggest how to do this with filterDeep

GaborTorma commented 4 years ago

Thanx! Same data, same predicate, only different function. You can use this pen: https://codepen.io/gabortorma/pen/LYpJyjd

YuriGor commented 4 years ago

https://codepen.io/yurigor/pen/OJyBLEY?editors=0010

(in your codepen markup or css was broken a bit so I created a new one from template and just copied your code)

GaborTorma commented 4 years ago

Thanx for your help. The options is perfect. Thanx! But I found a new problem when we use omiting with filterDeep. I create a new issue.