ast-get-values-by-key3.1.0

Extract values and paths from AST by keys OR set them by keys

Quick Take

import { strict as assert } from "assert";
import { getByKey } from "ast-get-values-by-key";

// GETTER
// ======

// returns "object-path" notation paths where arrays use dots:
assert.deepEqual(
  getByKey(
    {
      parsed: [
        {
          tag: "html",
        },
      ],
    },
    "tag" // value to search for
  ),
  [{ val: "html", path: "parsed.0.tag" }]
);

// SETTER
// ======

assert.deepEqual(
  getByKey(
    {
      parsed: [
        {
          tag: "html",
        },
      ],
      foo: {
        tag: null,
      },
      bar: {
        tag: null,
      },
    },
    "tag", // value to search for
    [123, 456] // pot of values to pick from (one result not enough)
  ),
  {
    parsed: [
      {
        tag: 123,
      },
    ],
    foo: {
      tag: 456,
    },
    bar: {
      tag: null, // value pot was depleted and there was nothing left to put here
    },
  }
);

Examples

Purpose

There are many ways to work with AST's — huge nested trees of objects and arrays. This program is one of the possible ways.

Two arguments trigger the GET mode — it returns an array of objects with value-path findings.

If you map that into desired values array and rerun it, this time putting desired values as a third input argument, you get the SET mode.

API

getByKey(
  input, 
  whatToFind, 
  [replacement]
)
  • If two arguments are given, it's getter. You'll receive an array of zero or more plain objects with keys: val and path, where path follows object-path opens in a new tab notation.

  • If three arguments are given, it's setter. You'll receive a copy of original input, changed accordingly.

This library does not mutate any input arguments.

Input argument Type Obligatory? Description
input Any yes Something to work upon
whatToFind String or array of strings yes Key names to look for. You can use matcher opens in a new tab wildcards in them.

Getter

To search ("get") put two input arguments, for example:

const findings = getByKey(source, ["*cles"]);

See the examples section. Paths are using object-path opens in a new tab notation. Where vanilla JS path would use brackets to address array elements: nested[0].cutticles, object-path notation uses dots still: nested.0.cutticles. The rest is the same.

Setter

To set values, put three input arguments, for example:

const result = getByKey(source, ["*cles"], ["a", "b", "c"]);

The third argument, ["a", "b", "c"] above, is the pot of values to put for each finding. The idea is that you'd use a getter first, prepare the amended values array, then feed it again into this program and change the input (AST or whatever plain object or array or whatever).

Changelog

See it in the monorepo opens in a new tab, on GitHub.

Contributing

To report bugs or request features or assistance, raise an issue on GitHub opens in a new tab.

Any code contributions welcome! All Pull Requests will be dealt promptly.

Licence

MIT opens in a new tab

Copyright © 2010–2021 Roy Revelt and other contributors

Related packages:

📦 object-path opens in a new tab
Access deep object properties using a path
📦 ast-monkey 7.15.0
Traverse and edit AST
📦 ast-get-object 2.1.0
Getter/setter for nested parsed HTML AST's, querying objects by key/value pairs
📦 ast-contains-only-empty-space 2.1.0
Does AST contain only empty space?
📦 ast-monkey-traverse-with-lookahead 2.1.0
Utility library to traverse AST, reports upcoming values
📦 ast-deep-contains 3.1.0
Like t.same assert on array of objects, where element order doesn't matter
📦 ast-compare 2.1.0
Compare anything: AST, objects, arrays, strings and nested thereof