Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/papb/tree-shortcut
Simplify an object tree with a shortcut. TypeScript supported.
https://github.com/papb/tree-shortcut
javascript tree tree-structure typescript
Last synced: 5 days ago
JSON representation
Simplify an object tree with a shortcut. TypeScript supported.
- Host: GitHub
- URL: https://github.com/papb/tree-shortcut
- Owner: papb
- License: mit
- Created: 2020-09-02T23:44:34.000Z (over 4 years ago)
- Default Branch: main
- Last Pushed: 2022-01-24T18:57:57.000Z (almost 3 years ago)
- Last Synced: 2024-12-23T00:52:44.380Z (13 days ago)
- Topics: javascript, tree, tree-structure, typescript
- Language: TypeScript
- Homepage:
- Size: 31.3 KB
- Stars: 1
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
- License: license
Awesome Lists containing this project
README
# tree-shortcut ![Build Status](https://github.com/papb/tree-shortcut/workflows/CI/badge.svg) [![install size](https://packagephobia.com/badge?p=tree-shortcut)](https://packagephobia.com/result?p=tree-shortcut)
> Simplify an object tree with a shortcut. TypeScript supported.
## Install
```
$ npm install tree-shortcut
```## Purpose
This module allows you to simplify a tree structure (i.e., any recursive object/array structure) by replacing objects with the value of one of its keys.
For example, you may want to convert `[{ a: 1, b: 2 }, { a: 3, d: 4 }]` into `[1, 3]` (replacing each object by its value on `'a'`).
This module provides a `treeShortcut` function that takes a tree and a simple _shortcut description_ and returns a deeply-cloned tree with a little change: the nested access of your choice is replaced by a shortcut. This allows you to simplify a complex tree of data, skipping information that you do not need.
The _shortcut description_ is a set of three strings:
- `shortcutTriggerProp`: The name of the property in which the shortcut begins
- `shortcutTargetProp`: The name of the nested property, target of the shortcut
- `shortcutName`: The name of the new property that will replace `shortcutTriggerProp`, whose value will be the one of the target property.The provided object is unchanged.
The example below will make this clear.
_You can also read the [detailed algorithm description](https://github.com/papb/tree-shortcut#detailed-algorithm-description) if you want._
## Example
```js
const treeShortcut = require('tree-shortcut');const tree = {
items: [
{
foo: { bar: [1, 2, 3] },
},
{
foo: { bar: [4, 5], baz: true },
},
{
foo: { baz: false },
},
{
foo: null,
},
],
};const newTree = treeShortcut(tree, 'foo', 'bar', 'foobar');
console.log(newTree);
//=> {
// items: [
// {
// foobar: [1, 2, 3]
// },
// {
// foobar: [4, 5]
// },
// {
// foobar: undefined
// },
// {
// foobar: undefined
// }
// ]
// }
```## API
### treeShortcut(tree, shortcutTriggerProp, shortcutTargetProp, shortcutName)
#### tree
Type: Anything
If it is indeed a tree (i.e. an array or plain object), it will be copied and modified with the shortcut. Otherwise, it will be returned unchanged.
#### shortcutTriggerProp
Type: `string`
The name of the prop which will trigger the shortcut.
#### shortcutTargetProp
Type: `string`
The name of the child prop which will be used as target of the shortcut.
#### shortcutName
Type: `string`
The name of the new prop to replace the `shortcutTriggerProp` in the parent object where the shortcut was triggered.
## Detailed algorithm description
The `treeShortcut(tree, shortcutTriggerProp, shortcutTargetProp, shortcutName)` will do the following:
1. If `tree` is an array, shallow-clone it and recurse on each element. Otherwise:
2. If `tree` is not a plain object, just return the input (`tree`) unchanged. Otherwise:
3. If `tree` does not have a key named `shortcutTriggerProp`, shallow-clone it and recurse on each key-value pair. Otherwise:
4. Shallow-clone the `tree` object into `tree_clone`;
5. If `tree_clone` has a key named `shortcutName`, delete it;
6. For each (shallow) property in `tree_clone`:- If its name is `shortcutTriggerProp`, rename it to `shortcutName` and then:
a. If its `value` is a plain object, replace it with `value[shortcutTargetProp]`. Otherwise:
b. If its `value` is an array, recurse on its elements running steps `a`, `b` and `c`. Otherwise:
c. If its `value` is neither an array nor a plain object, replace it with `undefined`.
- Example: `{ a: 1 }` becomes `value[shortcutTargetProp]`;
- Example: `[{ a: 1 }, { a: 2 }]` becomes `[value[0][shortcutTargetProp], value[1][shortcutTargetProp]]`;
- Example: `[{ a: 1 }, 2]` becomes `[value[0][shortcutTargetProp], undefined]`;
- Example: `[null, undefined, new Date()]` becomes `[undefined, undefined, undefined]`;- Otherwise, recurse (i.e. call `treeShortcut`) on the value of the property;
7. Return `tree_clone`.
## TypeScript support
This module supports TypeScript by default. The return type of the `treeShortcut` method is properly constructed.
The tested versions are TS 4.1, 4.2, 4.3, 4.4 and 4.5.
Note: the new shortcut property will be set to `readonly` if (and only if) the inner property was `readonly`. If the inner property was deep into an array, the new shortcut property will be set to `readonly` if (and only if) the inner property was `readonly` on all leaves of that array.
Example:
```ts
import treeShortcut = require('tree-shortcut');const tree = {
items: [
{
foo: { bar: [1, 2, 3] },
},
{
foo: { bar: [4, 5], baz: true },
},
{
foo: { baz: false },
},
{
foo: null,
},
],
};const newTree = treeShortcut(tree, 'foo', 'bar', 'foobar');
type NewTreeType = typeof newTree;
//=> {
// items: Array<{ foobar: number[] | undefined }>;
// }const tree2 = {
items: [
{
foo: { bar: [1, 2, 3] },
},
{
foo: { bar: [4, 5], baz: true },
},
{
foo: { baz: false },
},
{
foo: null,
},
],
} as const;const newTree2 = treeShortcut(tree2, 'foo', 'bar', 'foobar');
type NewTree2Type = typeof newTree2;
//=> {
// readonly items: readonly [{
// readonly foobar: readonly [1, 2, 3];
// }, {
// readonly foobar: readonly [4, 5];
// }, {
// foobar: undefined;
// }, {
// foobar: undefined;
// }];
// }
```## Related
- [`direct-deep-map`](https://github.com/papb/direct-deep-map): Deep map values in a tree directly on the desired places, with strong TypeScript support. Original tree is unchanged.
## License
MIT © [Pedro Augusto de Paula Barbosa](https://github.com/papb)