npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

tree-shortcut

v2.0.0

Published

Simplify an object tree with a shortcut. TypeScript supported.

Downloads

35

Readme

tree-shortcut Build Status install size

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 if you want.

Example

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:

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