diff --git a/objects.js b/objects.js index ecdcf22..b71899e 100644 --- a/objects.js +++ b/objects.js @@ -1,3 +1,5 @@ +import { isObject } from './checks.js' + /** * Helper function to set an immutable property * @param {Object} source - object where the new property will be set @@ -55,5 +57,19 @@ export function defineDefaults(source, defaults) { * @returns {*} the object we wanted to clone */ export function cloneDeep(source) { - return JSON.parse(JSON.stringify(source)) + return structuredClone(source) +} + +/** + * Like Array.prototype.filter but for objects + * @param {Object} source - target object + * @param {Funciton} filter - filter function + * @return {Object} filtered source or the original source received + */ +export function filter(source, filter) { + return isObject(source) + ? Object.fromEntries( + Object.entries(source).filter(([key, value]) => filter(key, value)), + ) + : source } diff --git a/objects.spec.js b/objects.spec.js index 3fdc550..8083a1d 100644 --- a/objects.spec.js +++ b/objects.spec.js @@ -3,6 +3,7 @@ import { defineDefaults, defineProperties, defineProperty, + filter, } from './objects.js' import { expect } from 'chai' @@ -51,4 +52,16 @@ describe('Objects', function () { expect(clone.surname).to.be.not.ok expect(clone.name).to.be.equal('hello') }) + + it('filter', () => { + const source = { name: 'hello', class: 'test' } + const filtered = filter(source, (key) => key === 'name') + + expect(filtered.class).to.be.not.ok + expect(filtered.name).to.be.equal('hello') + }) + + it('filter (null)', () => { + expect(() => filter(null, (key) => key === 'name')).to.not.throw() + }) })