diff --git a/snippets/dig.md b/snippets/dig.md new file mode 100644 index 000000000..8cf692a0c --- /dev/null +++ b/snippets/dig.md @@ -0,0 +1,30 @@ +### dig + +Returns the target value in a nested JSON object, based on the given key. + +Use the `in` operator to check if `target` exists in `obj`. +If found, return the value of `obj[target]`, otherwise use `Object.values(obj)` and `Array.reduce()` to recursively call `dig` on each nested object until the first matching key/value pair is found. + +``` +const dig = (obj, target) => + target in obj + ? obj[target] + : Object + .values(obj) + .reduce((acc, val) => { + if (acc !== undefined) return acc; + if (typeof val === 'object') return dig(val, target); + }, undefined); +``` + +``` +const data = { + level1:{ + level2:{ + level3: 'some data' + } + } +}; +dig(data, 'level3'); // 'some data' +dig(data, 'level4'); // undefined +``` diff --git a/tag_database b/tag_database index a2b57d852..5da94c541 100644 --- a/tag_database +++ b/tag_database @@ -55,6 +55,7 @@ detectDeviceType:browser difference:array,math differenceBy:array,function differenceWith:array,function +dig:object,recursion digitize:math,array distance:math drop:array diff --git a/test/dig/dig.js b/test/dig/dig.js new file mode 100644 index 000000000..710fce0c9 --- /dev/null +++ b/test/dig/dig.js @@ -0,0 +1,15 @@ +const dig = (obj, target) => + target in obj + ? obj[target] + : Object + .values(obj) + .reduce((acc, val) => { + if (acc !== undefined) { + return acc; + } + if (typeof val === "object") { + return dig(val, target); + } + }, undefined); + +module.exports = dig; diff --git a/test/dig/dig.test.js b/test/dig/dig.test.js new file mode 100644 index 000000000..280272dce --- /dev/null +++ b/test/dig/dig.test.js @@ -0,0 +1,32 @@ +const expect = require("expect"); +const dig = require("./dig.js"); + +const data = { + level1:{ + level2:{ + level3: "some data", + level3f: false, + level3a: [1,2,3,4] + } + } +}; + +test("dig is a Function", () => { + expect(dig).toBeInstanceOf(Function); +}); + +test("Dig target success", () => { + expect(dig(data, "level3")).toEqual("some data"); +}); + +test("Dig target with falsey value", () => { + expect(dig(data, "level3f")).toEqual(false); +}); + +test("Dig target with array", () => { + expect(dig(data, "level3a")).toEqual([1,2,3,4]); +}); + +test("Unknown target return undefined", () => { + expect(dig(data, "level4")).toEqual(undefined); +});