Skip to content

𝑓(🐏) = πŸ‘, Ramda Sheep is a set of useful Ramda functions.

License

Notifications You must be signed in to change notification settings

Restuta/ramda-sheep

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

36 Commits
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

ramda-sheep

𝑓(🐏) = πŸ‘, A set of useful functions built on top of Ramda that are not in the core.

Function are defined in a readme for now.

If you are looking for more advanced set of extensions look at ramda-adjunct

get

String β†’ {s: a} β†’ a

Just like lodash get accepts . delimeted path instead of an array:

const pathGetter = R.compose(R.path, R.split('.'))
const get = R.curry((path, obj) => pathGetter(path)(obj))

usage:

get('a.b', {a: {b: 8}}) //8

set

String β†’ a β†’ {a} β†’ {a}

Sets a property on an object using given path, returns new object.

const pathSetter = R.compose(R.assocPath, R.split('.'))
const set = R.curry((path, value, obj) => pathSetter(path)(value, obj))

usage:

set('a.b.c', 8, {}) // {a: {b: {c: 8}}}

isNilOrEmpty

Obj β†’ Boolean

Checks if value is nil or empty.

const isNilOrEmpty = R.either(R.isNil, R.isEmpty)

differenceAllWith(predicate, listOfLists)

Same as differenceWith, but for multiple lists

  const differenceAllWith = R.curry((predicate, array) =>
    R.reduce(
      R.differenceWith(predicate),
      R.head(array),
      R.tail(array)
  ))

strReplaceAll(search, replacement, target)

Replaces all occurences of a string with given replacement string.

const strReplaceAll = R.curry((search, replacement, str) =>
	R.replace(new RegExp(search, 'g'), replacement, str),
)

usage:

R.pipe(
  strReplaceAll('&', 'ramda'), 
  strReplaceAll('x', 'is'),
  strReplaceAll('y', 'cool'),
)('& x y')
// outputs "ramda is cool"

replaceBy(predicate, replaceWithItems, originalItems)

((originalItem, itemToReplaceWith) β†’ Boolean) β†’ Array β†’ Array β†’ Array

Replaces original items with given array of items using predicate, if predicate returns true, item will be replaced in original items in-place (it's orignal index) with the item from "replaceWithItems".

  const replaceBy = R.curry((predicate, replaceWithItems, originalItems) =>
    R.compose(
      R.reduce(
        (acc, itemsMap) =>
          R.update(itemsMap.index, itemsMap.item, acc),
        originalItems
      ),
      R.map(replacementItem => ({
        item: replacementItem,
        index: R.findIndex(
          originalItem => predicate(originalItem, replacementItem),
          originalItems
        )
      }))
    )(replaceWithItems))

usage:

replaceBy((original, updated) => original.id === updated.id, updatedUsers, allUsers)

updateBy(predicate, item, target)

Updates first item found using given predicate with a new item. To update multiple items use replaceBy defined above.

const updateBy = R.curry((func, value, target) => {
  const index = R.findIndex(func, target);
  return index >= 0 ? R.update(index, value, target) : target;
});

usage:

updateBy(x => x === 1, 'hi', [0,1,2,3]) //? [ 0, 'hi', 2, 3 ] 

pluckPath(strPath, list)

Like R.pluck, but with string path as a first argument. R.pluck allows to specify property name, while pluckPath can work with propert pathes like myProp.otherProp.nestedProp

const pluckPath = R.pipe(
  R.split('.'),
  R.path,
  R.map,
)
const pluckPathCurr = R.curry((path, obj) => pluckPath(path)(obj))

usage:

const list = [
  { x: { y: 1} },
  { x: { y: 2} },
  { x: { y: 3} },
]

pluckPath('x.y')(list) // [1, 2, 3]

indexByWith

Like R.indexBy, but accepts additional tranformation function to transform value for the given key.

const R = require('ramda')

const indexByWith = R.curry((keygenFunc, fn, items) =>
  R.reduce(
    (acc, item) => {
      acc[keygenFunc(item)] = fn(item)
      return acc
    },
    {},
    items,
  ),
)

usage:

indexByWith(R.prop('foo'), item => ({ a: item }), [
  { foo: 1 },
  { foo: 2 },
  { foo: 3 },
])

reduceObj

Like R.reduce, but for objects.

const reduceObj = R.useWith(R.reduce, [R.identity, R.identity, R.toPairs]);

usage:

reduceObj((acc, [key, val]) => return acc, {}, obj)

transformObjectDeep

Recursively traverse object and apply transformer function to every [key, value] pair and form new object based on that. If transformation function returns undefined then those [key, value] paris get removed from the original object. Keeps arrays as-is, meaning object inside an array won't be transformed.

const reduceObj = R.useWith(R.reduce, [R.identity, R.identity, R.toPairs]);

// given key value pair return new key value pair or nothing
const removeEmptyKeysTransformer = ([key, val]) => {
  if (val === undefined) {
    return undefined;
  }
  return [key, val];
};

// transformer is a function that takes [key, value] and return transformed pair or undefined
// if undefined is returned that pair is going to be removed from the object. Recursively applied
// properties of the object. Keeps arrays as-is, meaning object inside an array won't be transformed.
// transformer is a function that takes [key, value] and return transformed pair or undefined
// if undefined is returned that pair is going to be removed from the object. Recursively applied
// properties of the object. Keeps arrays as-is, meaning object inside an array won't be transformed.
// Handles circular references. 
const transformObjectDeep = R.curry((transformer, obj, objectCache = undefined) => {
  const cache = objectCache || new Set();
  cache.add(obj);

  return reduceObj(
    (acc, [key, val]) => {
      if (!Array.isArray(val) && val !== null && typeof val === 'object') {
        // detecting circular references
        if (cache.has(val)) {
          log.warn(`πŸŒ€ Circular reference detected in "transformObjectDeep", skipping, key=${key}`);
          acc[key] = `[Circular]`;
          return acc;
        }

        cache.add(val);

        const transformedVal = transformObjectDeep(transformer, val, cache);

        acc[key] = transformedVal;
        return acc;
      }

      const transformedKeyVal = transformer([key, val]);

      if (transformedKeyVal === undefined) {
        return acc;
      }

      const [tKey, tVal] = transformedKeyVal;
      acc[tKey] = tVal;

      return acc;
    },
    {},
    obj,
  );
});

usage:

// given key value pair return new key value pair or nothing
const removeEmptyKeysTransformer = ([key, val]) => {
  if (val === undefined) {
    return undefined;
  }
  return [key, val];
};

transformObjectDeep(removeEmptyKeysTransformer, { x: 8, y: undefined } ); //output: { x: 8 }

findMaxBy

Func β†’ [a] β†’ a

Find element in a list that has max value specified in the provided path using path getter function.

const findMaxBy = R.curry((path, arr) =>
  R.pipe(R.reduce((acc, x) => (path(acc) > path(x) ? acc : x), {}))(arr),
)

usage:

const prs = [
	{ pullRequests: { totalCount: 10 } },
	{ pullRequests: { totalCount: 8 } },
	{ pullRequests: { totalCount: 20 } },
	{ pullRequests: { totalCount: 12 } },
]

findMaxBy(R.path(['pullRequests', 'totalCount']), prs) // outputs: { pullRequests: { totalCount: 20 } } 

Curated List of Libraries

Partial Lenses

About

𝑓(🐏) = πŸ‘, Ramda Sheep is a set of useful Ramda functions.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published