mariocasciaro / object-path

A tiny JavaScript utility to access deep properties using a path (for Node and the Browser)
MIT License
1.06k stars 84 forks source link

Get property itself not value of property #83

Open bhaidar opened 7 years ago

bhaidar commented 7 years ago

Hi, Can I use this utility to get the property itself rather than value?

For instance, I have a string path to a property, I want to delete that property from an object, so using this utility to find the property by string path, I get only its value and not a reference to it to use it later.

Any idea? Thanks

revelt commented 7 years ago

But you can use objectPath.del — it is the same thing, isn't it?

CavalcanteLeo commented 4 years ago

Im facing the same issue, but i don't want to delete, just to store the reference path in another object

revelt commented 4 years ago

@CavalcanteLeo My package ast-monkey-traverse does the traversal of objects and arrays; it does report object-path-compatible paths which can be used in object-path's methods like get() etc. In example below, I extract all paths in object-path notation of keys named foo, getting ["a.foo", "a.foo.bar.foo", "a.foo.d.e.foo"]:

// Extract paths of all object keys named "foo"

import { strict as assert } from "assert";
import op from "object-path";
import traverse from "ast-monkey-traverse";

const paths = [];
const source = {
  a: {
    foo: {
      bar: {
        foo: "c",
      },
      d: {
        e: {
          foo: "f",
        },
      },
    },
  },
};

traverse(source, (key, val, innerObj) => {
  // if currently an object is traversed, you get both "key" and "val"
  // if it's array, only "key" is present, "val" is undefined
  const current = val !== undefined ? val : key;
  if (
    // it's object (not array)
    val !== undefined &&
    // and has the key we need
    key === "foo"
  ) {
    // push the path to array in the outer scope
    paths.push(innerObj.path);
  }
  return current;
});
assert.deepEqual(paths, ["a.foo", "a.foo.bar.foo", "a.foo.d.e.foo"]);

// then process the paths in `object-path`:
// paths.forEach(path => { op.get(source, path) }) ... or something similar

Going further, globby could be used to filter the key names and so on...

The object-path could be extended with more methods but smaller size of the API is a virtue :)

CavalcanteLeo commented 4 years ago

I will look into it, thanks in advance

PAEz commented 4 years ago

Wouldnt this just be?.....

    let obj={a:{b:1}};
    let path = "a.b";
    let pos = path.lastIndexOf('.');
    let prop = pos ? path.substr(pos + 1) : path;
    let parentPath = pos ? path.substr(0, pos) : "";
    let parent = pos ? objectPath.get(obj, parentPath) : obj;

parent[prop]