Skip to content

Commit

Permalink
feat: add omitBy (#376)
Browse files Browse the repository at this point in the history
Closes #171
  • Loading branch information
wojpawlik authored and char0n committed Feb 19, 2018
1 parent 2f5173a commit c7c9c7e
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ declare namespace RamdaAdjunct {

interface Dictionary<T> { [key: string]: T; }

type DictPred<T> = (value: T, key: string) => boolean;

This comment has been minimized.

Copy link
@wojpawlik

wojpawlik Feb 19, 2018

Author Contributor

Just realized, this type signature doesn't include 3rd param, probably better would be something like

type DictPred<T, U extends Dictionary<T>> = (value: T, key: string, dictionary: U) => boolean;

This comment has been minimized.

Copy link
@guillaumearm

guillaumearm Feb 19, 2018

Collaborator

you right, and key and object args should be optional.
would you want to PR ?

This comment has been minimized.

Copy link
@wojpawlik

wojpawlik Feb 19, 2018

Author Contributor

No, I'm supposed to be working on my college stuff now, I'll pass, at least for now, feel free to fix it yourself. I also used very little TypeScript, I'm definitely not confident in my abilities there.

This comment has been minimized.

Copy link
@guillaumearm

guillaumearm Feb 19, 2018

Collaborator

no problem with that, I go for it.


export interface Static {
/**
* Checks if input value is `Array`.
Expand Down Expand Up @@ -488,6 +490,13 @@ declare namespace RamdaAdjunct {
(source: object): (obj: object) => object;
};

/**
* Returns a partial copy of an object containing only the keys
* that don't satisfy the supplied predicate.
*/
omitBy<T, U extends Dictionary<T>>(pred: DictPred<T>, obj: U): U;
omitBy<T, U extends Dictionary<T>>(pred: DictPred<T>): (obj: U) => U;

/**
* Weave a configuration into function returning the runnable monad like `Reader` or `Free`.
*/
Expand Down
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ export { default as mergeProps } from './mergeProps';
export { default as mergePaths } from './mergePaths';
export { default as mergeProp } from './mergeProp';
export { default as mergePath } from './mergePath';
export { default as omitBy } from './omitBy';
export { default as viewOr } from './viewOr';
export { default as hasPath } from './hasPath';
export { default as spreadProp } from './spreadProp';
Expand Down
25 changes: 25 additions & 0 deletions src/omitBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { complement, identity, pickBy, useWith } from 'ramda';

/* eslint-disable max-len */
/**
* Returns a partial copy of an object containing only the keys
* that don't satisfy the supplied predicate.
*
* @func omitBy
* @memberOf RA
* @since {@link https://char0n.github.io/ramda-adjunct/2.6.0|v2.6.0}
* @category Object
* @sig ((v, k) -> Boolean) -> {k: v} -> {k: v}
* @param {!Function} pred A predicate to determine whether or not a key should be included on the output object
* @param {!Object} obj The object to copy from
* @return {!Object} A new object only with properties that don't satisfy `pred`
*
* @example
*
* const isLowerCase = (val, key) => key.toLowerCase() === key;
* RA.omitBy(isLowerCase, {a: 1, b: 2, A: 3, B: 4}); //=> {A: 3, B: 4}
*/
/* eslint-enable max-len */
const omitBy = useWith(pickBy, [complement, identity]);

export default omitBy;
47 changes: 47 additions & 0 deletions test/omitBy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { notStrictEqual, deepStrictEqual } from 'assert';
import * as R from 'ramda';

import * as RA from '../src/index';
import eq from './shared/eq';


describe('omitBy', function () {
const obj = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6 };

it('creates a copy of the object', function () {
notStrictEqual(RA.omitBy(R.F, obj), obj);
deepStrictEqual(RA.omitBy(R.F, obj), obj);
});

it('when returning truthy, omits the key', function () {
eq(RA.omitBy(R.T, obj), {});
eq(RA.omitBy(R.always({}), obj), {});
eq(RA.omitBy(R.always(1), obj), {});
});

it('when returning falsy, keeps the key', function () {
eq(RA.omitBy(R.F, obj), obj);
eq(RA.omitBy(R.always(0), obj), obj);
eq(RA.omitBy(R.always(null), obj), obj);
});

it('is called with (val, key, obj)', function () {
eq(RA.omitBy(function (val, key, _obj) {
eq(_obj, obj);
return key === 'd' && val === 4;
}, obj), { a: 1, b: 2, c: 3, e: 5, f: 6 });
});

it('retrieves prototype properties', function () {
const F = function (param) { this.x = param };
F.prototype.y = 40; F.prototype.z = 50;
const foo = new F(30);
foo.v = 10; foo.w = 20;
eq(RA.omitBy(function (val) { return val >= 45 }, foo), { v: 10, w: 20, x: 30, y: 40 });
});

it('is curried', function () {
const copier = RA.omitBy(R.F);
eq(copier(obj), obj);
});
});

0 comments on commit c7c9c7e

Please sign in to comment.