An open API service indexing awesome lists of open source software.

https://github.com/YuriGor/deepdash

eachDeep, filterDeep, findDeep, someDeep, omitDeep, pickDeep, keysDeep etc.. Tree traversal library written in Underscore/Lodash fashion
https://github.com/YuriGor/deepdash

eachdeep filterdeep foreachdeep keysdeep lodash object paths traversal tree

Last synced: 5 months ago
JSON representation

eachDeep, filterDeep, findDeep, someDeep, omitDeep, pickDeep, keysDeep etc.. Tree traversal library written in Underscore/Lodash fashion

Awesome Lists containing this project

README

        

## 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](https://planzed.org/) - awesome cloud mind map app created by the author of deepdash.
Plz check it, it's free and I need [feedback](https://github.com/YuriGor/PlanZed.org) πŸ˜‰

[![All Contributors](https://img.shields.io/badge/all_contributors-13-orange.svg?style=flat-square)](#contributors-)
[![Known Vulnerabilities](https://snyk.io/test/npm/deepdash/badge.svg)](https://snyk.io/test/npm/deepdash) [![Travis (.org)](https://api.travis-ci.org/YuriGor/deepdash.svg?branch=master)](https://travis-ci.org/YuriGor/deepdash) [![Coverage Status](https://coveralls.io/repos/github/YuriGor/deepdash/badge.svg?branch=master)](https://coveralls.io/github/YuriGor/deepdash?branch=master)

[![NPM](https://nodei.co/npm/deepdash.png?compact=true)](https://nodei.co/npm/deepdash/)

### Installation
#### In a browser
Load [script](https://cdn.jsdelivr.net/npm/deepdash/browser/deepdash.min.js) after Lodash, then pass a lodash instance to the deepdash function:
```html

deepdash(_);
console.log(_.eachDeep); // --> new methods mixed into Lodash

```

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

console.log(deepdash.eachDeep); // --> all the methods just work

```
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:
```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
```
```js
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.
```js
import filterDeep from 'deepdash-es/filterDeep';
```
or
```js
import { filterDeep } from 'deepdash-es/standalone';
```
or
```js
import _ from 'lodash-es';
import getFilterDeep from 'deepdash-es/getFilterDeep';
const filterDeep = getFilterDeep(_);
```
or
```js
import _ from 'lodash-es';
import addFilterDeep from 'deepdash-es/addFilterDeep';
addFilterDeep(_);// --> _.filterDeep
```

## Demo
[Example react+redux app](https://codesandbox.io/s/github/YuriGor/deepdash-example-comments/) with nested comments filtered by Deepdash.([source is here](https://github.com/YuriGor/deepdash-example-comments/tree/master/))

## Methods

### eachDeep (forEachDeep)
β€Ί iterate over all the children and sub-children [πŸ“š see docs](https://deepdash.io/#eachdeep-foreachdeep)

expand example

let children = [/* expand to see */];

```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,
},
],
},
];
```

```js
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);
```

Console:

```
= 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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/BeBEqx?editors=0010)

### filterDeep
β€Ί deep filter object [πŸ“š see docs](https://deepdash.io/#filterdeep)

expand example

let children = [/* expand to see */];

```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,
},
],
},
];
```

```js
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;
})
);
```

Console:

```
= 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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/eaOaQg?editors=0010)

### findDeep
β€Ί find first matching deep meta-value [πŸ“š see docs](https://deepdash.io/#finddeep)

example a bit later

let children = [/* expand to see */];

```js
// next time
```

```js
// sorry
```

Console:

```
❀️

```

[Try it yourself (no yet) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor)

### findValueDeep
β€Ί find first matching deep value [πŸ“š see docs](https://deepdash.io/#findvaluedeep)

example a bit later

let children = [/* expand to see */];

```js
// next time
```

```js
// sorry
```

Console:

```
❀️

```

[Try it yourself (no yet) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor)

### findPathDeep
β€Ί find the path of the first matching deep value [πŸ“š see docs](https://deepdash.io/#findpathdeep)

example a bit later

let children = [/* expand to see */];

```js
// next time
```

```js
// sorry
```

Console:

```
❀️

```

[Try it yourself (no yet) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor)

### mapDeep
β€Ί get array of values processed by iteratee. [πŸ“š see docs](https://deepdash.io/#mapdeep)

expand example

```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) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor)

### mapValuesDeep
β€Ί get the object with same structure, but transformed values. [πŸ“š see docs](https://deepdash.io/#mapvaluesdeep)

expand example

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

[Try it yourself β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/yWBzGV?editors=0010)

### mapKeysDeep
β€Ί get the object with same values, but transformed keys. [πŸ“š see docs](https://deepdash.io/#mapkeysdeep)

expand example

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

[Try it yourself (no yet) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/)

### reduceDeep
β€Ί like reduce, but deep [πŸ“š see docs](https://deepdash.io/#reducedeep)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/ZNzmmR?editors=0010)

### someDeep
β€Ί returns true if some matching deep value found [πŸ“š see docs](https://deepdash.io/#somedeep)

example a bit later

let children = [/* expand to see */];

```js
// next time
```

```js
// sorry
```

Console:

```
❀️

```

[Try it yourself (no yet) β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor)

### pickDeep
β€Ί pick values by paths specified by endings or regexes [πŸ“š see docs](https://deepdash.io/#pickdeep)

expand example

let children = [/* expand to see */];

```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,
},
],
},
];
```

```js
console.log('\n = Pick name and description only = \n');

console.log(
_.pickDeep(children, ['name', 'description'])
);
```

Console:

```
= 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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/zQOVBR?editors=0010)

### omitDeep
β€Ί get object without paths specified by endings or regexes [πŸ“š see docs](https://deepdash.io/#omitdeep)

expand example

let children = [/* expand to see */];

```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,
},
],
},
];
```

```js
console.log('\n = Omit paths not ending with "e" = \n');

console.log(
_.omitDeep(children, /[^e]$/i, { onMatch: { skipChildren: false } }),
);
```

Console:

```
= 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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/YbKoNM?editors=0010)

### index
β€Ί get an object with all the paths as keys and corresponding values [πŸ“š see docs](https://deepdash.io/#index)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/rgBzdB?editors=0010)

### paths (keysDeep)
β€Ί get an array of paths [πŸ“š see docs](https://deepdash.io/#paths-keysdeep)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/mYbByL?editors=0010)

### condense
β€Ί condense sparse array [πŸ“š see docs](https://deepdash.io/#condense)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/oOKGXE?editors=0010)

### condenseDeep
β€Ί condense all the nested arrays [πŸ“š see docs](https://deepdash.io/#condensedeep)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/mgNBOa?editors=0010)

### exists
β€Ί like a `_.has` but returns `false` for empty array slots [πŸ“š see docs](https://deepdash.io/#exists)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/MRNOQB?editors=0010)

### pathToString
β€Ί convert an array to string path (opposite to _.toPath) [πŸ“š see docs](https://deepdash.io/#pathtostring)

expand example

```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 β€Ίβ€Ίβ€Ί](https://codepen.io/yurigor/pen/joNXGv?editors=0010)

### See [full docs](https://deepdash.io) for details.

## Contributors ✨

Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/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](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!