Skip to content

Commit

Permalink
feat: omit function
Browse files Browse the repository at this point in the history
  • Loading branch information
Soontao committed Dec 29, 2020
1 parent 3bcc413 commit 89f9b0f
Show file tree
Hide file tree
Showing 3 changed files with 85 additions and 9 deletions.
74 changes: 74 additions & 0 deletions src/omit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import arrayMap from './.internal/arrayMap';
import baseClone from './.internal/baseClone';
import baseUnset from './.internal/baseUnset';
import castPath from './.internal/castPath';
import { CLONE_DEEP_FLAG, CLONE_FLAT_FLAG, CLONE_SYMBOLS_FLAG } from './.internal/CONSTANTS';
import copyObject from './.internal/copyObject';
import flatRest from './.internal/flatRest';
import getAllKeysIn from './.internal/getAllKeysIn';
import isPlainObject from './isPlainObject';
import { Path } from './types';

/**
* Used by `_.omit` to customize its `_.cloneDeep` use to only clone plain
* objects.
*
* @internal
* @ignore
* @private
* @param value The value to inspect.
* @param key The key of the property to inspect.
* @returns Returns the uncloned value or `undefined` to defer cloning to `_.cloneDeep`.
*/
function customOmitClone(value: any): any {
return isPlainObject(value) ? undefined : value;
}
/**
* @internal
* @ignore
* @private
*/
const internalOmit = flatRest((object: any, paths: any) => {
let result = {};
if (object == null) {
return result;
}
let isDeep = false;
paths = arrayMap(paths, (path) => {
path = castPath(path, object);
isDeep || (isDeep = path.length > 1);
return path;
});
copyObject(object, getAllKeysIn(object), result);
if (isDeep) {
result = baseClone(result, CLONE_DEEP_FLAG | CLONE_FLAT_FLAG | CLONE_SYMBOLS_FLAG, customOmitClone);
}
let length = paths.length;
while (length--) {
baseUnset(result, paths[length]);
}
return result;
});

/**
* The opposite of [[pick]];
*
* this method creates an object composed of the own and inherited enumerable property paths of object that are not omitted.
* @category Object
* @since 5.18.0
* @param object
* @param paths
* @example
* ```js
* const object = { 'a': 1, 'b': '2', 'c': 3 };
* omit(object, ['a', 'c']);
* // => { 'b': '2' }
* ```
*/
export function omit<T extends any>(object: T, ...paths: Array<Path>): Partial<T>;
export function omit(object: any, ...paths: any): any {
return object == null ? {} : internalOmit(object, ...paths);
}


export default omit;
6 changes: 3 additions & 3 deletions src/pick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ type Path = string | number | Array<Path>
*
* @since 5.7.0
* @category Object
* @param {Object} object The source object.
* @param {...(string|string[])} [paths] The property paths to pick.
* @returns {Object} Returns the new object.
* @param object The source object.
* @param paths The property paths to pick.
* @returns Returns the new object.
* @example
*
* ```js
Expand Down
14 changes: 8 additions & 6 deletions test/omit.js → test/omit.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
// @ts-nocheck
import * as assert from 'assert';
import lodashStable from 'lodash';
import { args, toArgs, objectProto, stringProto } from './utils';
import { each } from '../src';
import omit from '../src/omit';
import { objectProto, stringProto, toArgs } from './utils';

describe('omit', () => {

const args = toArgs(['a', 'c']),
object = { 'a': 1, 'b': 2, 'c': 3, 'd': 4 },
nested = { 'a': 1, 'b': { 'c': 2, 'd': 3 } };
Expand All @@ -14,7 +16,7 @@ describe('omit', () => {
});

it('should support deep paths', () => {
assert.deepStrictEqual(omit(nested, 'b.c'), { 'a': 1, 'b': { 'd': 3} });
assert.deepStrictEqual(omit(nested, 'b.c'), { 'a': 1, 'b': { 'd': 3 } });
});

it('should support path arrays', () => {
Expand All @@ -27,7 +29,7 @@ describe('omit', () => {
it('should omit a key over a path', () => {
const object = { 'a.b': 1, 'a': { 'b': 2 } };

lodashStable.each(['a.b', ['a.b']], (path) => {
each(['a.b', ['a.b']], (path) => {
assert.deepStrictEqual(omit(object, path), { 'a': { 'b': 2 } });
});
});
Expand All @@ -37,7 +39,7 @@ describe('omit', () => {
});

it('should return an empty object when `object` is nullish', () => {
lodashStable.each([null, undefined], (value) => {
each([null, undefined], (value) => {
objectProto.a = 1;
const actual = omit(value, 'valueOf');
delete objectProto.a;
Expand All @@ -60,7 +62,7 @@ describe('omit', () => {
});

it('should not mutate `object`', () => {
lodashStable.each(['a', ['a'], 'a.b', ['a.b']], (path) => {
each(['a', ['a'], 'a.b', ['a.b']], (path) => {
const object = { 'a': { 'b': 2 } };
omit(object, path);
assert.deepStrictEqual(object, { 'a': { 'b': 2 } });
Expand Down

0 comments on commit 89f9b0f

Please sign in to comment.