diff --git a/snippets/hasKey.md b/snippets/hasKey.md new file mode 100644 index 000000000..797034f65 --- /dev/null +++ b/snippets/hasKey.md @@ -0,0 +1,33 @@ +--- +title: hasKey +tags: object,recursion,intermediate +--- + +Returns `true` if the target value exists in a JSON object, `false` otherwise. + +Check if the key contains `.`, use `String.prototype.split('.')[0]` to get the first part and store as `_key`. +Use `typeof` to check if the contents of `obj[key]` are an `object` and, if so, call `hasKey` with that object and the remainder of the `key`. +Otherwise, use `Object.keys(obj)` in combination with `Array.prototype.includes()` to check if the given `key` exists. + +```js +const hasKey = (obj, key) => { + if (key.includes('.')) { + let _key = key.split('.')[0]; + if (typeof obj[_key] === 'object') + return hasKey(obj[_key], key.slice(key.indexOf('.') + 1)) + } + return Object.keys(obj).includes(key); +} +``` + +```js +let obj = { + a: 1, b: { c: 4 }, 'd.e': 5 +} +hasKey(obj, 'a'); // true +hasKey(obj, 'b'); // true +hasKey(obj, 'b.c'); // true +hasKey(obj, 'd.e'); // true +hasKey(obj, 'd'); // false +hasKey(obj, 'f'); // false +``` diff --git a/test/hasKey.test.js b/test/hasKey.test.js new file mode 100644 index 000000000..1aaf1b787 --- /dev/null +++ b/test/hasKey.test.js @@ -0,0 +1,33 @@ +const {hasKey} = require('./_30s.js'); + +const data = { + a: 1, b: { c: 4 }, 'd.e': 5 +}; + +test('hasKey is a Function', () => { + expect(hasKey).toBeInstanceOf(Function); +}); + +test('hasKey returns true for simple property', () => { + expect(hasKey(data, 'a')).toBe(true); +}); + +test('hasKey returns true for object property', () => { + expect(hasKey(data, 'b')).toBe(true); +}); + +test('hasKey returns true for nested property', () => { + expect(hasKey(data, 'b.c')).toBe(true); +}); + +test('hasKey returns true for property with dots', () => { + expect(hasKey(data, 'd.e')).toBe(true); +}); + +test('hasKey returns false for non-existent property', () => { + expect(hasKey(data, 'f')).toBe(true); +}); + +test('hasKey returns false for virtual nested property', () => { + expect(hasKey(data, 'd')).toBe(false); +});