Skip to content

Commit

Permalink
v1.0.2
Browse files Browse the repository at this point in the history
Support wildcard
  • Loading branch information
eliottvincent committed Apr 29, 2024
1 parent 3b8bdc2 commit cfbf618
Show file tree
Hide file tree
Showing 5 changed files with 135 additions and 15 deletions.
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ console.log(dotly.get(obj, "a.b.c"));
### Gets a value at a path within an object
`get(object, path, defaultValue)` returns the value at the specified path:
* `object` must the object from which to get the value
* `path` must be a string representing the path, using dot notation
* `path` must be a string representing the path, using dot notation (supports wildcard with `*`)
* `defaultValue` can be used as a default value

```js
Expand All @@ -37,6 +37,10 @@ var obj = {
a: {
b: {
c: "hello"
},

d: {
c: "hello bis"
}
}
};
Expand All @@ -52,6 +56,9 @@ console.log(get(obj, "a.b.c.d"));

console.log(get(obj, "a.b.c.d", "hallo"));
// 'hallo'

console.log(get(obj, "a.*.c"));
// [{path: 'a.b.c', value: 'hello'}, {path: 'a.d.c', value: 'hello bis'}]
```

### Sets a value at a path within an object
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "dotly",
"version": "1.0.1",
"version": "1.0.2",
"description": "Access properties within an object, using dot-notation",
"author": "Eliott Vincent <[email protected]>",
"main": "src/index.js",
Expand Down
70 changes: 70 additions & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Object.defineProperty(exports, "__esModule", {
* @return {string|number|boolean|object} The value within the object
*/
var get = function(object, path = "", defaultValue = undefined) {
if (path.includes("*")) {
return __getWildcard(object, path, defaultValue);
}

var _value = object,
_path = path.split(".");

Expand Down Expand Up @@ -79,6 +83,72 @@ var remove = function(object, path) {
}
};

/**
* Gets a value at a path within an object (wildcard)
* @private
* @param {object} object
* @param {string} [path]
* @param {string|number|boolean|object} [defaultValue]
* @return {string|number|boolean|object} The value within the object
*/
var __getWildcard = function(object, path = "", defaultValue = undefined) {
var _path = path.split("."),
_results = __search(object, _path);

if (_results.length) {
return _results
}

return defaultValue;
};

/**
* Searches object values based on path (recursive)
* @private
* @param {object} object
* @param {object} path
* @param {object} currentPath
* @param {object} [results]
* @return {object} Results
*/
var __search = function(object, path, currentPath = [], results = []) {
if (path.length === 0) {
results.push({
$d : true,

path : currentPath.join("."),
value : object
});

return results;
}

var _part = path[0],
_path = path.slice(1);

if (object && typeof object === "object") {
if (_part === "*") {
for (var _key in object) {
__search(
object[_key],
_path,
currentPath.concat(_key),
results
);
}
} else if (object[_part] !== undefined) {
__search(
object[_part],
_path,
currentPath.concat(_part),
results
);
}
}

return results;
};

exports.get = get;
exports.set = set;
exports.remove = remove;
Expand Down
65 changes: 54 additions & 11 deletions test/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,26 @@ var OBJECT = {
two: 2,

b: {
three: 3
three: 3,
hello: "hello b"
},

c: {
hello: "hello c"
}
},

u: undefined,
n: null,
f: false,
zero: 0
z: 0
};

var DEFAULT_VALUE = "four";

module.exports = {
testGet: function(test) {
test.expect(32);
test.expect(41);

var actual = src.get;
var message = "get should be defined."
Expand All @@ -50,11 +55,49 @@ module.exports = {
[OBJECT, "u", OBJECT.u],
[OBJECT, "n", OBJECT.n],
[OBJECT, "f", OBJECT.f],
[OBJECT, "zero", OBJECT.zero]
[OBJECT, "z", OBJECT.z],

[OBJECT, "*", [
{$d: true, path: "one", value: OBJECT.one},
{$d: true, path: "true", value: OBJECT.true},
{$d: true, path: "a", value: OBJECT.a},
{$d: true, path: "u", value: OBJECT.u},
{$d: true, path: "n", value: OBJECT.n},
{$d: true, path: "f", value: OBJECT.f},
{$d: true, path: "z", value: OBJECT.z}
]],
[OBJECT, "*.*", [
{$d: true, path: "a.two", value: OBJECT.a.two},
{$d: true, path: "a.b", value: OBJECT.a.b},
{$d: true, path: "a.c", value: OBJECT.a.c}
]],
[OBJECT, "*.two", [
{$d: true, path: "a.two", value: OBJECT.a.two},
]],
[OBJECT, "a.*", [
{$d: true, path: "a.two", value: OBJECT.a.two},
{$d: true, path: "a.b", value: OBJECT.a.b},
{$d: true, path: "a.c", value: OBJECT.a.c}
]],
[OBJECT, "a.*.*", [
{$d: true, path: "a.b.three", value: OBJECT.a.b.three},
{$d: true, path: "a.b.hello", value: OBJECT.a.b.hello},
{$d: true, path: "a.c.hello", value: OBJECT.a.c.hello}
]],
[OBJECT, "a.b.*", [
{$d: true, path: "a.b.three", value: OBJECT.a.b.three},
{$d: true, path: "a.b.hello", value: OBJECT.a.b.hello}
]],
[OBJECT, "a.*.hello", [
{$d: true, path: "a.b.hello", value: OBJECT.a.b.hello},
{$d: true, path: "a.c.hello", value: OBJECT.a.c.hello},
]],
[OBJECT, "a.*.hello.unexistingKey", undefined],
[OBJECT, "a.c.hello.*", undefined]
]
.forEach((entry) => {
var actual = src.get(entry[0], entry[1]);
test.equals(actual, entry[2], "usage should work.");
test.deepEqual(actual, entry[2], "get usage should work.");
});

[
Expand All @@ -76,11 +119,11 @@ module.exports = {
[OBJECT, "u", DEFAULT_VALUE, DEFAULT_VALUE],
[OBJECT, "n", DEFAULT_VALUE, OBJECT.n],
[OBJECT, "f", DEFAULT_VALUE, OBJECT.f],
[OBJECT, "zero", DEFAULT_VALUE, OBJECT.zero],
[OBJECT, "z", DEFAULT_VALUE, OBJECT.z]
]
.forEach((entry) => {
var actual = src.get(entry[0], entry[1], entry[2]);
test.equals(actual, entry[3], "usage with defaultValue should work.");
test.equals(actual, entry[3], "get usage with defaultValue should work.");
});

test.done();
Expand All @@ -106,15 +149,15 @@ module.exports = {
[{}, "u", OBJECT.u],
[{}, "n", OBJECT.n],
[{}, "f", OBJECT.f],
[{}, "zero", OBJECT.zero],
[{}, "z", OBJECT.z],

[OBJECT, "a.b.three", DEFAULT_VALUE, DEFAULT_VALUE]
]
.forEach((entry) => {
src.set(entry[0], entry[1], entry[2]);

var actual = src.get(entry[0], entry[1]);
test.equals(actual, entry[2], "usage should work.");
test.equals(actual, entry[2], "set usage should work.");
});

test.done();
Expand All @@ -140,13 +183,13 @@ module.exports = {
[OBJECT, "u", OBJECT.u],
[OBJECT, "n", OBJECT.n],
[OBJECT, "f", OBJECT.f],
[OBJECT, "zero", OBJECT.zero]
[OBJECT, "z", OBJECT.z]
]
.forEach((entry) => {
src.remove(entry[0], entry[1]);

var actual = src.get(entry[0], entry[1]);
test.equals(actual, undefined, "usage should work.");
test.equals(actual, undefined, "remove usage should work.");
});

test.done();
Expand Down

0 comments on commit cfbf618

Please sign in to comment.