5.3.9 โ€ข Published 4 years ago

deepdash v5.3.9

Weekly downloads
18,102
License
MIT
Repository
github
Last release
4 years ago

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

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);
 = 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

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;
      })
  );
 = 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

// next time
// sorry
โค๏ธ

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

findValueDeep

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

// next time
// sorry
โค๏ธ

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

findPathDeep

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

// next time
// sorry
โค๏ธ

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

mapDeep

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

  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

  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

  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

  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

// next time
// sorry
โค๏ธ

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

pickDeep

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

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'])
  );
 = 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

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 } }),
  );
 = 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

  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

  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

  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

  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

  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

  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):

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

5.3.9

4 years ago

5.3.8

4 years ago

5.3.7

4 years ago

5.3.6

4 years ago

5.3.5

4 years ago

5.3.4

4 years ago

5.3.3

4 years ago

5.3.2

4 years ago

5.3.1

4 years ago

5.3.0

4 years ago

5.2.1

4 years ago

5.2.0

4 years ago

5.1.2

5 years ago

5.1.1

5 years ago

5.0.6

5 years ago

5.1.0

5 years ago

5.0.5

5 years ago

5.0.4

5 years ago

5.0.3

5 years ago

5.0.2

5 years ago

5.0.1

5 years ago

5.0.0

5 years ago

4.6.1

5 years ago

4.6.2

5 years ago

4.6.0

5 years ago

4.5.6

5 years ago

4.5.5

5 years ago

4.5.4

5 years ago

4.5.3

5 years ago

4.5.2

5 years ago

4.5.0

5 years ago

4.5.1

5 years ago

4.4.1

5 years ago

4.4.2

5 years ago

4.4.0

5 years ago

4.3.2

5 years ago

4.3.1

5 years ago

4.3.0

5 years ago

4.2.18

5 years ago

4.2.17

5 years ago

4.2.16

5 years ago

4.2.15

5 years ago

4.2.14

5 years ago

4.2.13

5 years ago

4.2.12

5 years ago

4.2.11

5 years ago

4.2.10

5 years ago

4.2.9

5 years ago

4.2.8

5 years ago

4.2.7

6 years ago

4.2.6

6 years ago

4.2.5

6 years ago

4.2.4

6 years ago

4.2.3

6 years ago

4.2.2

6 years ago

4.2.1

6 years ago

4.2.0

6 years ago

4.1.0

6 years ago

4.0.0

6 years ago

3.1.3

6 years ago

3.1.2

6 years ago

3.1.1

6 years ago

3.1.0

6 years ago

2.1.3

6 years ago

2.1.2

6 years ago

2.1.1

6 years ago

2.1.0

6 years ago

2.0.2

6 years ago

2.0.1

6 years ago

2.0.0

6 years ago

1.9.5

6 years ago

1.9.4

6 years ago

1.9.3

6 years ago

1.9.2

6 years ago

1.9.1

6 years ago

1.9.0

6 years ago

1.8.1

6 years ago

1.8.0

6 years ago

1.7.2

6 years ago

1.7.1

6 years ago

1.7.0

6 years ago

1.6.7

6 years ago

1.6.6

6 years ago

1.6.5

6 years ago

1.6.4

6 years ago

1.6.3

6 years ago

1.6.2

6 years ago

1.6.1

6 years ago

1.6.0

6 years ago

1.5.5

6 years ago

1.5.4

6 years ago

1.5.3

6 years ago

1.5.2

6 years ago

1.5.1

6 years ago

1.5.0

6 years ago

1.4.1

6 years ago

1.4.0

6 years ago

1.3.2

6 years ago

1.3.1

6 years ago

1.2.6

6 years ago

1.2.5

6 years ago

1.2.4

6 years ago

1.2.3

6 years ago

1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.3

6 years ago

1.1.2

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago