ๅŒ…่ฏฆ็ป†ไฟกๆฏ

deepdash

YuriGor383.9kMIT5.3.9

โž” ๐ƒeep standalone lib / ๐‹odash extension: โœ“ eachDeep โœ“ filterDeep โœ“ mapDeep โœ“ reduceDeep โœ“ pickDeep โœ“ omitDeep โœ“ keysDeep โœ“ index โœ“ condenseDeep โ‹ฎ Parents stack โ‹ฎ Circular check โ‹ฎ Leaves only mode โ‹ฎ Children mode โ‹ฎ cherry-pick โ‹ฎ esm

lodash, each deep, filter deep, map deep

่‡ช่ฟฐๆ–‡ไปถ

Deepdash

eachDeep, filterDeep, findDeep, someDeep, omitDeep, pickDeep, keysDeep etc.. Tree traversal library written in Underscore/Lodash fashion. Standalone or as a Lodash mixin extension

Deepdash lib is used in PlanZed.org - awesome cloud mind map app created by the author of deepdash.
Plz check it, it's free and I need feedback ๐Ÿ˜‰

All Contributors Known Vulnerabilities Travis (.org) Coverage Status
NPM

Installation

In a browser

Load script after Lodash, then pass a lodash instance to the deepdash function:

<script src="https://cdn.jsdelivr.net/npm/lodash/lodash.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js"></script>
<script>
  deepdash(_);
  console.log(_.eachDeep); // --> new methods mixed into Lodash
</script>

If you don't use Lodash - there is a standalone version:

<script src="https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.standalone.min.js"></script>
<script>
  console.log(deepdash.eachDeep); // --> all the methods just work
</script>

Standalone Deepdash weighs more then "dry" version, because it includes some of cherry-picked Lodash methods it depends on. But it's better to use Standalone version, than include full Lodash just as dependency, if you don't need Lodash.

Using npm:

npm i --save deepdash

In Node.js:

// load Lodash if you need it
const _ = require('lodash');
//mixin all the methods into Lodash object
require('deepdash')(_);
// or cherry-pick method you only need and mix it into lodash
require('deepdash/addFilterDeep')(_);
// or cherry-pick method separately if you don't want to mutate Lodash instance
const filterDeep = require('deepdash/getFilterDeep')(_);
// If you don't need Lodash - there is standalone version
const deepdash = require('deepdash/standalone'); // full
const filterDeep = require('deepdash/filterDeep'); // or separate standalone methods

There is also deepdash as ES6 module

npm i --save deepdash-es
import lodash from 'lodash-es';
import deepdash from 'deepdash-es';
const _ = deepdash(lodash);

in the ES package there are same cherry-pick and/or standalone methods as in the main package.

import filterDeep from 'deepdash-es/filterDeep';

or

import { filterDeep } from 'deepdash-es/standalone';

or

import _ from 'lodash-es';
import getFilterDeep from 'deepdash-es/getFilterDeep';
const filterDeep = getFilterDeep(_);

or

import _ from 'lodash-es';
import addFilterDeep from 'deepdash-es/addFilterDeep';
addFilterDeep(_);// --> _.filterDeep

Demo

Example react+redux app with nested comments filtered by Deepdash.(source is here)

Methods

eachDeep (forEachDeep)

โ€บ iterate over all the children and sub-children ๐Ÿ“š see docs

<summary>expand example</summary>
<summary> let children = [/ expand to see /];</summary> js let children = [ { description: 'description for node 1', comment: 'comment for node 1', note: 'note for node 1', name: 'node 1', bad: false, children: [ { description: 'description for node 1.1', comment: 'comment for node 1.1', note: 'note for node 1.1', name: 'node 1.1', bad: false, }, { description: 'description for node 1.2', comment: 'comment for node 1.2', note: 'note for node 1.2', name: 'node 1.2', good: true, }, { description: 'description for node 1.3', comment: 'comment for node 1.3', note: 'note for node 1.3', name: 'node 1.3', bad: true, good: false, }, ], }, { description: 'description for node 2', comment: 'comment for node 2', note: 'note for node 2', name: 'node 2', good: true, children: [ { description: 'description for node 2.1', comment: 'comment for node 2.1', note: 'note for node 2.1', name: 'node 2.1', bad: false, }, { description: 'description for node 2.2', comment: 'comment for node 2.2', note: 'note for node 2.2', name: 'node 2.2', good: true, }, { description: 'description for node 2.3', comment: 'comment for node 2.3', note: 'note for node 2.3', name: 'node 2.3', bad: true, good: false, }, ], }, { description: 'description for node 3', comment: 'comment for node 3', note: 'note for node 3', name: 'node 3', bad: true, good: false, children: [ { description: 'description for node 3.1', comment: 'comment for node 3.1', note: 'note for node 3.1', name: 'node 3.1', bad: false, }, { description: 'description for node 3.2', comment: 'comment for node 3.2', note: 'note for node 3.2', name: 'node 3.2', good: true, }, { description: 'description for node 3.3', comment: 'comment for node 3.3', note: 'note for node 3.3', name: 'node 3.3', bad: true, good: false, }, ], }, ];
  function displayField(val, key, parent, context) {
      if (_.isArray(parent)) {
        key = '[' + key + ']';
      }
      console.log(
        _.repeat('   ', context.depth) +
          'โ†’ ' +
          key +
          ': ' +
          (_.isArray(val)
            ? '[' + val.length + ']'
            : _.isObject(val)
            ? '{' + (val.name || '') + '}'
            : val)
      );
    }

    console.log('\n = Iterate over tree (each child object) = \n');

    _.eachDeep(children, displayField, { childrenPath: 'children' });

    console.log('\n = Iterate over object (each field) = \n');

    _.eachDeep(children, displayField);
<summary>Console: </summary> = Iterate over tree (each child object) = โ†’ [0]: {node 1} โ†’ [0]: {node 1.1} โ†’ [1]: {node 1.2} โ†’ [2]: {node 1.3} โ†’ [1]: {node 2} โ†’ [0]: {node 2.1} โ†’ [1]: {node 2.2} โ†’ [2]: {node 2.3} โ†’ [2]: {node 3} โ†’ [0]: {node 3.1} โ†’ [1]: {node 3.2} โ†’ [2]: {node 3.3} = Iterate over object (each field) = โ†’ [0]: {node 1} โ†’ description: description for node 1 โ†’ comment: comment for node 1 โ†’ note: note for node 1 โ†’ name: node 1 โ†’ bad: false โ†’ children: [3] โ†’ [0]: {node 1.1} โ†’ description: description for node 1.1 โ†’ comment: comment for node 1.1 โ†’ note: note for node 1.1 โ†’ name: node 1.1 โ†’ bad: false โ†’ [1]: {node 1.2} โ†’ description: description for node 1.2 โ†’ comment: comment for node 1.2 โ†’ note: note for node 1.2 โ†’ name: node 1.2 โ†’ good: true โ†’ [2]: {node 1.3} โ†’ description: description for node 1.3 โ†’ comment: comment for node 1.3 โ†’ note: note for node 1.3 โ†’ name: node 1.3 โ†’ bad: true โ†’ good: false โ†’ [1]: {node 2} โ†’ description: description for node 2 โ†’ comment: comment for node 2 โ†’ note: note for node 2 โ†’ name: node 2 โ†’ good: true โ†’ children: [3] โ†’ [0]: {node 2.1} โ†’ description: description for node 2.1 โ†’ comment: comment for node 2.1 โ†’ note: note for node 2.1 โ†’ name: node 2.1 โ†’ bad: false โ†’ [1]: {node 2.2} โ†’ description: description for node 2.2 โ†’ comment: comment for node 2.2 โ†’ note: note for node 2.2 โ†’ name: node 2.2 โ†’ good: true โ†’ [2]: {node 2.3} โ†’ description: description for node 2.3 โ†’ comment: comment for node 2.3 โ†’ note: note for node 2.3 โ†’ name: node 2.3 โ†’ bad: true โ†’ good: false โ†’ [2]: {node 3} โ†’ description: description for node 3 โ†’ comment: comment for node 3 โ†’ note: note for node 3 โ†’ name: node 3 โ†’ bad: true โ†’ good: false โ†’ children: [3] โ†’ [0]: {node 3.1} โ†’ description: description for node 3.1 โ†’ comment: comment for node 3.1 โ†’ note: note for node 3.1 โ†’ name: node 3.1 โ†’ bad: false โ†’ [1]: {node 3.2} โ†’ description: description for node 3.2 โ†’ comment: comment for node 3.2 โ†’ note: note for node 3.2 โ†’ name: node 3.2 โ†’ good: true โ†’ [2]: {node 3.3} โ†’ description: description for node 3.3 โ†’ comment: comment for node 3.3 โ†’ note: note for node 3.3 โ†’ name: node 3.3 โ†’ bad: true โ†’ good: false

Try it yourself โ€บโ€บโ€บ

filterDeep

โ€บ deep filter object ๐Ÿ“š see docs

<summary>expand example</summary>
<summary> let children = [/ expand to see /];</summary> js let children = [ { description: 'description for node 1', comment: 'comment for node 1', note: 'note for node 1', name: 'node 1', bad: false, children: [ { description: 'description for node 1.1', comment: 'comment for node 1.1', note: 'note for node 1.1', name: 'node 1.1', bad: false, }, { description: 'description for node 1.2', comment: 'comment for node 1.2', note: 'note for node 1.2', name: 'node 1.2', good: true, }, { description: 'description for node 1.3', comment: 'comment for node 1.3', note: 'note for node 1.3', name: 'node 1.3', bad: true, good: false, }, ], }, { description: 'description for node 2', comment: 'comment for node 2', note: 'note for node 2', name: 'node 2', good: true, children: [ { description: 'description for node 2.1', comment: 'comment for node 2.1', note: 'note for node 2.1', name: 'node 2.1', bad: false, }, { description: 'description for node 2.2', comment: 'comment for node 2.2', note: 'note for node 2.2', name: 'node 2.2', good: true, }, { description: 'description for node 2.3', comment: 'comment for node 2.3', note: 'note for node 2.3', name: 'node 2.3', bad: true, good: false, }, ], }, { description: 'description for node 3', comment: 'comment for node 3', note: 'note for node 3', name: 'node 3', bad: true, good: false, children: [ { description: 'description for node 3.1', comment: 'comment for node 3.1', note: 'note for node 3.1', name: 'node 3.1', bad: false, }, { description: 'description for node 3.2', comment: 'comment for node 3.2', note: 'note for node 3.2', name: 'node 3.2', good: true, }, { description: 'description for node 3.3', comment: 'comment for node 3.3', note: 'note for node 3.3', name: 'node 3.3', bad: true, good: false, }, ], }, ];
  console.log('\n = Filter tree (good children) = \n');

  console.log(
    _.filterDeep(children, 'good', { childrenPath: 'children' })
  );

  console.log('\n = Filter object (names of good children) = \n');

  console.log(
      _.filterDeep(children, (val, key, parent) => {
        if (key == 'name' && parent.good) return true;
      })
  );
<summary>Console:</summary> = Filter tree (good children) = [ { "description": "description for node 1", "comment": "comment for node 1", "note": "note for node 1", "name": "node 1", "bad": false, "children": [ { "description": "description for node 1.2", "comment": "comment for node 1.2", "note": "note for node 1.2", "name": "node 1.2", "good": true } ] }, { "description": "description for node 2", "comment": "comment for node 2", "note": "note for node 2", "name": "node 2", "good": true, "children": [ { "description": "description for node 2.2", "comment": "comment for node 2.2", "note": "note for node 2.2", "name": "node 2.2", "good": true } ] }, { "description": "description for node 3", "comment": "comment for node 3", "note": "note for node 3", "name": "node 3", "bad": true, "good": false, "children": [ { "description": "description for node 3.2", "comment": "comment for node 3.2", "note": "note for node 3.2", "name": "node 3.2", "good": true } ] } ] = Filter object (names of good children) = [ { "children": [ { "name": "node 1.2" } ] }, { "name": "node 2", "children": [ { "name": "node 2.2" } ] }, { "children": [ { "name": "node 3.2" } ] } ]

Try it yourself โ€บโ€บโ€บ

findDeep

โ€บ find first matching deep meta-value ๐Ÿ“š see docs

<summary>example a bit later</summary>
<summary> let children = [/ expand to see /];</summary> js // next time
// sorry
<summary>Console:</summary> โค๏ธ

Try it yourself (no yet) โ€บโ€บโ€บ

findValueDeep

โ€บ find first matching deep value ๐Ÿ“š see docs

<summary>example a bit later</summary>
<summary> let children = [/ expand to see /];</summary> js // next time
// sorry
<summary>Console:</summary> โค๏ธ

Try it yourself (no yet) โ€บโ€บโ€บ

findPathDeep

โ€บ find the path of the first matching deep value ๐Ÿ“š see docs

<summary>example a bit later</summary>
<summary> let children = [/ expand to see /];</summary> js // next time
// sorry
<summary>Console:</summary> โค๏ธ

Try it yourself (no yet) โ€บโ€บโ€บ

mapDeep

โ€บ get array of values processed by iteratee. ๐Ÿ“š see docs

<summary>expand example</summary> js let res = _.mapDeep( { hello: { from: { the: 'deep world', and: 'deepdash' } } }, (v) => v.toUpperCase(), { leavesOnly: true } ); // res -> ['DEEP WORLD','DEEPDASH']

Try it yourself (no yet) โ€บโ€บโ€บ

mapValuesDeep

โ€บ get the object with same structure, but transformed values. ๐Ÿ“š see docs

<summary>expand example</summary> js let res = _.mapValuesDeep( { hello: { from: { the: 'deep world' } } }, (v) => v.toUpperCase(), { leavesOnly: true } ); // res -> { hello: { from: { the: 'DEEP WORLD' } } }

Try it yourself โ€บโ€บโ€บ

mapKeysDeep

โ€บ get the object with same values, but transformed keys. ๐Ÿ“š see docs

<summary>expand example</summary> js let res = _.mapKeysDeep( { hello: { from: { the: 'deep world' } } }, (v, k) => k.toUpperCase() ); // res -> { HELLO: { FROM: { THE: 'deep world' } } }

Try it yourself (no yet) โ€บโ€บโ€บ

reduceDeep

โ€บ like reduce, but deep ๐Ÿ“š see docs

<summary>expand example</summary> js let max = _.reduceDeep({ a: 2, b: 3, c: { d: 6, e: [1, 5, 8] } }, (acc, value, key, parent, ctx) => { if (typeof value == 'number' && (typeof acc != 'number' || value > acc)) return value; return undefined; } ); // max == 8

Try it yourself โ€บโ€บโ€บ

someDeep

โ€บ returns true if some matching deep value found ๐Ÿ“š see docs

<summary>example a bit later</summary>
<summary> let children = [/ expand to see /];</summary> js // next time
// sorry
<summary>Console:</summary> โค๏ธ

Try it yourself (no yet) โ€บโ€บโ€บ

pickDeep

โ€บ pick values by paths specified by endings or regexes ๐Ÿ“š see docs

<summary>expand example</summary>
<summary> let children = [/ expand to see /];</summary> js let children = [ { description: 'description for node 1', comment: 'comment for node 1', note: 'note for node 1', name: 'node 1', bad: false, children: [ { description: 'description for node 1.1', comment: 'comment for node 1.1', note: 'note for node 1.1', name: 'node 1.1', bad: false, }, { description: 'description for node 1.2', comment: 'comment for node 1.2', note: 'note for node 1.2', name: 'node 1.2', good: true, }, { description: 'description for node 1.3', comment: 'comment for node 1.3', note: 'note for node 1.3', name: 'node 1.3', bad: true, good: false, }, ], }, { description: 'description for node 2', comment: 'comment for node 2', note: 'note for node 2', name: 'node 2', good: true, children: [ { description: 'description for node 2.1', comment: 'comment for node 2.1', note: 'note for node 2.1', name: 'node 2.1', bad: false, }, { description: 'description for node 2.2', comment: 'comment for node 2.2', note: 'note for node 2.2', name: 'node 2.2', good: true, }, { description: 'description for node 2.3', comment: 'comment for node 2.3', note: 'note for node 2.3', name: 'node 2.3', bad: true, good: false, }, ], }, { description: 'description for node 3', comment: 'comment for node 3', note: 'note for node 3', name: 'node 3', bad: true, good: false, children: [ { description: 'description for node 3.1', comment: 'comment for node 3.1', note: 'note for node 3.1', name: 'node 3.1', bad: false, }, { description: 'description for node 3.2', comment: 'comment for node 3.2', note: 'note for node 3.2', name: 'node 3.2', good: true, }, { description: 'description for node 3.3', comment: 'comment for node 3.3', note: 'note for node 3.3', name: 'node 3.3', bad: true, good: false, }, ], }, ];
  console.log('\n = Pick name and description only = \n');

  console.log(
    _.pickDeep(children, ['name', 'description'])
  );
<summary>Console:</summary> = Pick name and description only = [ { "description": "description for node 1", "name": "node 1", "children": [ { "description": "description for node 1.1", "name": "node 1.1" }, { "description": "description for node 1.2", "name": "node 1.2" }, { "description": "description for node 1.3", "name": "node 1.3" } ] }, { "description": "description for node 2", "name": "node 2", "children": [ { "description": "description for node 2.1", "name": "node 2.1" }, { "description": "description for node 2.2", "name": "node 2.2" }, { "description": "description for node 2.3", "name": "node 2.3" } ] }, { "description": "description for node 3", "name": "node 3", "children": [ { "description": "description for node 3.1", "name": "node 3.1" }, { "description": "description for node 3.2", "name": "node 3.2" }, { "description": "description for node 3.3", "name": "node 3.3" } ] } ]

Try it yourself โ€บโ€บโ€บ

omitDeep

โ€บ get object without paths specified by endings or regexes ๐Ÿ“š see docs

<summary>expand example</summary>
<summary> let children = [/ expand to see /];</summary> js let children = [ { description: 'description for node 1', comment: 'comment for node 1', note: 'note for node 1', name: 'node 1', bad: false, children: [ { description: 'description for node 1.1', comment: 'comment for node 1.1', note: 'note for node 1.1', name: 'node 1.1', bad: false, }, { description: 'description for node 1.2', comment: 'comment for node 1.2', note: 'note for node 1.2', name: 'node 1.2', good: true, }, { description: 'description for node 1.3', comment: 'comment for node 1.3', note: 'note for node 1.3', name: 'node 1.3', bad: true, good: false, }, ], }, { description: 'description for node 2', comment: 'comment for node 2', note: 'note for node 2', name: 'node 2', good: true, children: [ { description: 'description for node 2.1', comment: 'comment for node 2.1', note: 'note for node 2.1', name: 'node 2.1', bad: false, }, { description: 'description for node 2.2', comment: 'comment for node 2.2', note: 'note for node 2.2', name: 'node 2.2', good: true, }, { description: 'description for node 2.3', comment: 'comment for node 2.3', note: 'note for node 2.3', name: 'node 2.3', bad: true, good: false, }, ], }, { description: 'description for node 3', comment: 'comment for node 3', note: 'note for node 3', name: 'node 3', bad: true, good: false, children: [ { description: 'description for node 3.1', comment: 'comment for node 3.1', note: 'note for node 3.1', name: 'node 3.1', bad: false, }, { description: 'description for node 3.2', comment: 'comment for node 3.2', note: 'note for node 3.2', name: 'node 3.2', good: true, }, { description: 'description for node 3.3', comment: 'comment for node 3.3', note: 'note for node 3.3', name: 'node 3.3', bad: true, good: false, }, ], }, ];
  console.log('\n = Omit paths not ending with "e" = \n');

  console.log(
    _.omitDeep(children, /[^e]$/i, { onMatch: { skipChildren: false } }),
  );
<summary>Console:</summary> = Omit paths not ending with "e" = [ { "note": "note for node 1", "name": "node 1", "children": [ { "note": "note for node 1.1", "name": "node 1.1" }, { "note": "note for node 1.2", "name": "node 1.2" }, { "note": "note for node 1.3", "name": "node 1.3" } ] }, { "note": "note for node 2", "name": "node 2", "children": [ { "note": "note for node 2.1", "name": "node 2.1" }, { "note": "note for node 2.2", "name": "node 2.2" }, { "note": "note for node 2.3", "name": "node 2.3" } ] }, { "note": "note for node 3", "name": "node 3", "children": [ { "note": "note for node 3.1", "name": "node 3.1" }, { "note": "note for node 3.2", "name": "node 3.2" }, { "note": "note for node 3.3", "name": "node 3.3" } ] } ]

Try it yourself โ€บโ€บโ€บ

index

โ€บ get an object with all the paths as keys and corresponding values ๐Ÿ“š see docs

<summary>expand example</summary> js let index = _.index( { a: { b: { c: [1, 2, 3], 'hello world': {}, }, }, }, { leavesOnly: true } ); console.log(index); Console: { 'a.b.c[0]': 1, 'a.b.c[1]': 2, 'a.b.c[2]': 3, 'a.b["hello world"]': {} }

Try it yourself โ€บโ€บโ€บ

paths (keysDeep)

โ€บ get an array of paths ๐Ÿ“š see docs

<summary>expand example</summary> js let paths = _.paths( { a: { b: { c: [1, 2, 3], 'hello world': {}, }, }, }, { leavesOnly: false } ); console.log(paths); Console: [ 'a', 'a.b', 'a.b.c', 'a.b.c[0]', 'a.b.c[1]', 'a.b.c[2]', 'a.b["hello world"]' ]

Try it yourself โ€บโ€บโ€บ

condense

โ€บ condense sparse array ๐Ÿ“š see docs

<summary>expand example</summary> js let arr = ['a', 'b', 'c', 'd', 'e']; delete arr[1]; console.log(arr); delete arr[3]; console.log(arr); _.condense(arr); console.log(arr); Console: [ 'a', <1 empty item>, 'c', 'd', 'e' ] [ 'a', <1 empty item>, 'c', <1 empty item>, 'e' ] [ 'a', 'c', 'e' ]

Try it yourself โ€บโ€บโ€บ

condenseDeep

โ€บ condense all the nested arrays ๐Ÿ“š see docs

<summary>expand example</summary> js let obj = { arr: ['a', 'b', { c: [1, , 2, , 3] }, 'd', 'e'] }; delete obj.arr[1]; delete obj.arr[3]; _.condenseDeep(obj); console.log(obj); Console: { arr: [ 'a', { c: [ 1, 2, 3 ] }, 'e' ] }

Try it yourself โ€บโ€บโ€บ

exists

โ€บ like a _.has but returns false for empty array slots ๐Ÿ“š see docs

<summary>expand example</summary> js var obj = [, { a: [, 'b'] }]; console.log(_.exists(obj, 0)); // false console.log(_.exists(obj, 1)); // true console.log(_.exists(obj, '[1].a[0]')); // false console.log(_.exists(obj, '[1].a[1]')); // true

Try it yourself โ€บโ€บโ€บ

pathToString

โ€บ convert an array to string path (opposite to _.toPath) ๐Ÿ“š see docs

<summary>expand example</summary> js console.log(_.pathToString(['a', 'b', 'c', 'defg', 0, '1', 2.3] ,'prefix1', 'prefix2', '[3]')); // prefix1.prefix2[3].a.b.c.defg[0][1]["2.3"] console.log(_.pathToString(['"', '"', '"'])); // ["\\""]["\\""]["\\""] console.log(_.pathToString('it.s.a.string')); // it.s.a.string

Try it yourself โ€บโ€บโ€บ

See full docs for details.

Contributors โœจ

Thanks goes to these wonderful people (emoji key):


Raz Sinay

๐Ÿ’ป ๐Ÿ““ ๐Ÿค”

Florent

๐Ÿ› ๐Ÿ““

JoeSchr

๐Ÿค” ๐Ÿ““

Matt Black

๐Ÿค”

Lukas Siemon

๐Ÿค” ๐Ÿ““ ๐Ÿ’ป ๐Ÿ“ข โš ๏ธ

crapthings

๐Ÿค”

Corrado Masciullo

๐Ÿ› ๐Ÿค”

Jed Richards

๐Ÿš‡

Kolja Zuelsdorf

๐Ÿ› ๐Ÿ““ ๐Ÿ’ก

Noval Agung Prayogo

๐Ÿ’ฌ

Nathan Tomsic

๐Ÿค”

madflow

๐Ÿ’ฌ

Matthew Kirkley

๐Ÿ› ๐Ÿค”

Torma Gรกbor

๐Ÿ› ๐Ÿค” ๐Ÿ““

Andreas Richter

๐Ÿ› ๐Ÿ““

James

๐Ÿ› ๐Ÿ’ป ๐Ÿ“– ๐Ÿ““

rxliuli

๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

TeleMediaCC

๐Ÿ›

Nicolas Coutin

๐Ÿ’ต ๐Ÿ““

barrct

๐Ÿ› ๐Ÿ“–

casamia918

๐Ÿ› ๐Ÿ’ป ๐Ÿ“–

ferreirix

๐Ÿค”

John Camden

๐Ÿ›

Joshua

๐Ÿ’ป ๐Ÿ“–

This project follows the all-contributors specification. Contributions of any kind welcome!

ๆ›ดๆ–ฐๆ—ฅๅฟ—

Change Log

v5-1-0

(2020-06-07)

Features added

  • mapValuesDeep - context.skipChildren added to let user override default behavior

Bugs fixed

  • mapValuesDeep - method will skip children if value changed type from/to array and use given value as is (#60)

v5-0-0

(2020-03-21)

Breaking Changes

  • mapDeep renamed to mapValuesDeep to conform to Lodash map/mapValues/mapKeys family of methods.
  • mapDeep re-implemented to return an array of deep values processed by iteratee (same as _.map in Lodash)

Features added

  • mapKeysDeep implemented - returns object with same values but keys modified by iteratee (same as _.mapKeys in Lodash)

v4-6-0

(2020-03-21) Features added

  • pathToString prefixes args added to prepend result path correctly. (Used internally to optimize a bit by re-using already stringified paths)
  • TypeScript definitions added, see this "discussion" for details.

v4-5-0

(2020-02-16)

Features added

  • findDeep implemented - returns first meta-value {value, key, parent, context}, iteratee agree with, if none - returns undefined.
  • findValueDeep implemented - returns first value, iteratee agree with, if none - returns undefined. Be carefull, some deep value may exists but also be undefined.
  • findPathDeep implemented - returns first path, iteratee agree with, if none - returns undefined. Be carefull with includeRoot, object itself, passed as data source, also has path undefined.
  • someDeep implemented - returns true if found some deep value, iteratee agree with, if none - return false (just shorthand wrapper for findDeep)

v4-4-0

(2019-12-16)

Features added

  • message field (if exists) of error thrown by iteratee will be appended by current path, to speed up debug.

v4-3-0

(2019-12-7)

Features added

  • eachDeep now supports break.(as context.break function passed into iteratee)

Bugs fixed

  • filterDeep didn't use onUndefined options for parents skipped due leavesOnly mode.

v4-2-0

(2019-04-19)

Features added

  • mapDeep implemented

v4-1-0

(2019-04-05)

Features added

  • reduceDeep implemented

v4-0-0

(2019-04-05)

Breaking Changes

  • in the browser deepdash doesn't try to patch existing global _ variable. It now exposes global deepdash function and user should pass a lodash instance to this function manually.
  • source object will be passed to the iteratee/predicate as a very first value with undefined key/path/parent (see includeRoot option)
  • indexate renamed to index.
  • in case of completely rejected object filterDeep returns null instead of empty {}/[]
  • if not an object passed as a source to filterDeep source will be returned if it passes the filter, otherwise null.
  • context.treeChildrenPath renamed to childrenPath.
  • isTreeChildren, isTreeNode iteratee sub-parameters deprecated (since they are always true in 'tree' mode and false in the 'object' mode)
  • regexp children path support dropped to optimise tree walking
  • tree sub-object option deprecated, tree.children renamed to childrenPath, tree.rootIsChildren renamed to rootIsChildren

Features added

  • cherry-pick separate methods now available as standalone functions or as a lodash mixins.
  • standalone version now available
  • deepdash-es package created for importing as es6 module. It's just a content of es folder from main repo.
  • includeRoot option added to eachDeep, index, paths (keysDeep) and filterDeep methods.
  • leavesOnly implemented for tree mode. eachDeep now also has leavesOnly option.

v3-1-0

(2019-03-08) โœฟโƒโ€

Breaking Changes

  • keepUndefined option removed from the filterDeep method. Use onUndefined:{keepIfEmpty:true}, instead.
  • keys argument of the omitDeep and pickDeep methods became paths

Features added

  • tree option added to the filterDeep method.
  • tree option added to the indexate method.
  • tree option added to the paths (keysDeep) method.
  • predicate option of the filterDeep method is Lodash _.iteratee.
  • cloneDeep option of the filterDeep now can be set to false.
  • callbackAfterIterate option added to the eachDeep method.
  • onTrue onUndefined and onFalse options added to the filterDeep method. cloneDeep, keepIfEmpty, skipChildren default values can be overwritten for each condition.
  • onMatched and onNotMatched options added to the omitDeep and pickDeep methods.
  • custom object replies from filterDeep iteratee, with cloneDeep, keepIfEmpty, skipChildren and empty fields now are supported.

Bugs fixed

  • filterDeep method continues to iterate over object's children if it passed the filter.

v2-1-0

(2019-03-02)

Features added

  • tree option added to the eachDeep method. Now it's much easier to iterate over tree with known children collection field name / path

Bugs fixed

  • Circular reference detector false positive for similar parent/child structure

v2-0-0

(2019-02-21)

Breaking Changes

  • iteratee/predicate arguments order/structure changed to mimic native js array predicates

Features added

  • checkCircular option added to the eachDeep method.
  • pickDeep method implemented.

v1-9-5

(2019-02-09)

no changelog earlier, sorry