Socket
Socket
Sign inDemoInstall

list-fns

Package Overview
Dependencies
0
Maintainers
1
Versions
10
Alerts
File Explorer

Advanced tools

Install Socket

Detect and block malicious and high-risk dependencies

Install

    list-fns

A collection of utility functions to be used with .map, .filter, .sort and .reduce


Version published
Weekly downloads
129
increased by48.28%
Maintainers
1
Created
Weekly downloads
 

Changelog

Source

1.4.0

  • isDefined: adds check for null
  • or: adds check for null
  • has: adds check for null, updates return type to work better with required but nullable properties

Readme

Source

list-fns

npm version

This library contains higher order functions that simplify common list operations, similar to what you'd find in lodash or ramda. Unlike these libraries, list-fns is designed specifically to be used with the native array methods.

These functions have not been rigorously tested for performance so they are currently not recommended for use with large datasets.

Example

import { byProperty, get, uniqueByProperty } from "list-fns";

const people = [
  { name: "Jack", age: 44 },
  { name: "Jack", age: 60 },
  { name: "Jane", age: 20 },
];

// Inline implementation:
people
  .filter(
    (person, index) => index === people.findIndex(p => p.name === person.name)
  )
  .sort((a, b) => (a.age < b.age ? -1 : a.age > b.age ? 1 : 0))
  .map(person => person.name); // ["Jane", "Jack"]

// With list functions:
people
  .filter(uniqueByProperty("name"))
  .sort(byProperty("age"))
  .map(get("name")); // ["Jane", "Jack"]

Install

npm install list-fns

A note about sorting

This library contains functions to be used with [].sort(). Always be mindful of the fact that .sort() and .reverse() will mutate the original list. If .sort() is the first method you're calling on a list you should probably clone it first in order to avoid unexpected behavior:

[...list].sort();
list.slice().sort();
[].concat(list).sort();

Functions

Table of contents

by

by: <T>(func: (el: T) => any) => (a: T, b: T) => 0 | 1 | -1

Use with: sort

Sort the elements by func(element) . Supports sorting by boolean values (elements that are true first).

[{ a: 2 }, { a: 1 }].sort(by(el => el.a)); // Returns [{ a: 1 }, { a: 2 }]

Implementation

const by = <T>(func: (el: T) => any) => (a: T, b: T) => {
  const A = func(a),
    B = func(b);
  if (typeof A === "boolean") return A && !B ? -1 : !A && B ? 1 : 0;
  return A < B ? -1 : A > B ? 1 : 0;
}

byProperty

byProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey) => (a: TObject, b: TObject) => 0 | 1 | -1

Use with: sort

Sort the elements by element[key] (can also be an array index). Supports sorting by boolean values (elements that are true first).

[{ a: 2 }, { a: 1 }].sort(byProperty('a')); // Returns [{ a: 1 }, { a: 2 }]
[["a", 2], ["a", 1]].sort(byProperty(1)); // Returns [["a", 1], ["a", 2]]

Implementation

const byProperty = <TObject extends object, TKey extends keyof TObject>(
  key: TKey
) => by<TObject>(get(key))

byValue

byValue: (a: number, b: number) => 0 | 1 | -1

Use with: sort

Sort a list of numbers. This is useful because javascript sorts numbers as string, meaning that [25, 100] results in [100, 25] since "2" is greater than "1"

[100, 25].sort(); // Returns [100, 25]
[100, 25].sort(byValue); // Returns [25, 100]

Implementation

const byValue = (a: number, b: number) => (a < b ? -1 : a > b ? 1 : 0)

countBy

countBy: <T>(func: (el: T) => boolean) => (acc: number, el: T) => number

Use with: reduce

Returns the number of times func returned true for the list elements. A number must be passed to the second argument of reduce . Can be combined with boolean-returning functions like is , isnt , propertyIs or propertyIsOneOf .

["a", "a", "b"].reduce(countBy(el => el === "a"), 0); // Returns 2
["a", "a", "b"].reduce(countBy(is("a")), 0); // Returns 2

Implementation

const countBy = <T>(func: (el: T) => boolean) => (acc: number, el: T) =>
  acc + (func(el) ? 1 : 0)

duplicates

duplicates: (el: unknown, _: number, list: unknown[]) => boolean

Use with: filter

Returns duplicates

[1, 1, 1, 2].filter(duplicates); // Returns [1, 1, 1]

Implementation

const duplicates = duplicatesBy(el => el)

duplicatesBy

duplicatesBy: <T>(func: (el: T) => unknown) => (el: T, _: number, list: T[]) => boolean

Use with: filter

Returns all duplicates compared by func(element)

[{ a: 1 }, { a : 1 }, { a: 2 }].filter(duplicatesBy(el => el.a)); // Returns [{ a: 1 }, { a: 1 }]

Implementation

const duplicatesBy = <T>(func: (el: T) => unknown) => (
  el: T,
  _: number,
  list: T[]
) => {
  let n = 0;
  for (let i = 0; i < list.length; i++) {
    if (n >= 2) return true;
    if (func(list[i]) === func(el)) n++;
  }
  return false;
}

duplicatesByProperty

duplicatesByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey) => (el: TObject, _: number, list: TObject[]) => boolean

Use with: filter

Returns duplicates compared by element[key]

[{ a: 1 }, { a: 1 }].filter(duplicatesByProperty('a')); // Return [{ a: 1 }, { a: 1 }]

Implementation

const duplicatesByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey
) => duplicatesBy<TObject>(get(key))

exclude

exclude: <T>(list: T[]) => (el: T) => boolean

Use with: filter

Removes the provided elements from the list

[1, 2, 3, 4].filter(exclude([1, 2])); // Returns [3, 4]

Implementation

const exclude = <T>(list: T[]) => (el: T) =>
  findIndex(list, a => a === el) === -1

excludeBy

excludeBy: <T>(func: (el: T) => unknown, list: T[]) => (el: T) => boolean

Use with: filter

Removes the provided elements from the list compared by running func on elements in both lists

[{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }]
  .filter(excludeBy(el => el.a, [{ a: 1 }, { a: 2 }]));
  // Returns [{ a: 3 }, { a: 4 }]

Implementation

const excludeBy = <T>(func: (el: T) => unknown, list: T[]) => (el: T) =>
  findIndex(list, a => func(a) === func(el)) === -1

excludeByProperty

excludeByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey, list: TObject[]) => (el: TObject) => boolean

Use with: filter

Removes the provided elements from the list compared at key

[{ a: 1 }, { a: 2 }, { a: 3 }, { a: 4 }]
  .filter(excludeByProperty('a', [{ a: 1 }, { a: 2 }]));
  // Returns [{ a: 3 }, { a: 4 }]

Implementation

const excludeByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey,
  list: TObject[]
) => excludeBy(get(key), list)

get

get: {
  <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1], TKey3 extends keyof TObject[TKey1][TKey2]>(key1: TKey1, key2: TKey2, key3: TKey3): (obj: TObject) => TObject[TKey1][TKey2][TKey3];
  <TObject extends object, TKey1 extends keyof TObject, TKey2 extends keyof TObject[TKey1]>(key1...;
}

Use with map or filter

Returns element[key] (can also be an array index). Supports up to three keys of depth.

[{ a: 1 }, { a: 2 }].map(get('a')); // Returns [1, 2]
[["a", 1], ["a", 2]].map(get(1)); // Returns [1, 2]
[{ a: { b: { c: 1 } } }].map(get('a', 'b', 'c')); // Returns [1]

Implementation

export function get<
  TObject extends object,
  TKey1 extends keyof TObject,
  TKey2 extends keyof TObject[TKey1],
  TKey3 extends keyof TObject[TKey1][TKey2]
>(key1: TKey1, key2?: TKey2, key3?: TKey3) {
  return (obj: TObject) => {
    if (key3 && key2)
      return obj && obj[key1] && obj[key1][key2] && obj[key1][key2][key3];
    if (key2) return obj && obj[key1] && obj[key1][key2];
    return obj && obj[key1];
  };
}

groupBy

groupBy: <K extends string, V>(func: (el: V) => K | undefined) => (acc: Record<K, V[]>, el: V) => Record<K, V[]>

Use with: reduce

Given a key-returning function, returns the elements grouped in an object according to the returned keys. A second argument must be passed to reduce . For javascript an empty object is enough. For typescript an object with properties or a type cast may be required.

[{ age: 10 }, { age: 80 }].reduce(
  groupBy(el => (el.age > 30 ? "old" : "young")),
  { old: [], young: [] }
); // Returns { old: [{ age: 80 }], young: [{ age: 10 }]}

Implementation

const groupBy = <K extends string, V>(
  func: (el: V) => K | undefined
) => (acc: Record<K, V[]>, el: V): Record<K, V[]> => {
  const groupName = func(el);
  if (!groupName) return acc;
  if (!acc[groupName]) acc[groupName] = [];
  acc[groupName].push(el);
  return acc;
}

groupByMany

groupByMany: <K extends string, V>(func: (el: V) => K[] | undefined) => (acc: Record<K, V[]>, el: V) => Record<K, V[]>

Use with: reduce

Given a function func that returns a list of keys, returns an object containing the elements grouped by the returned keys. Unlike the groupBy function, elements can appear several times in this object. Good for grouping objects by properties that are arrays. An empty object must be passed as the second argument to reduce

const b1: B = { items: ["a", "b"] };
const b2: B = { items: ["a"] };

[b1, b2].reduce(groupByMany(b => b.items), {});
// Returns { a: [{ items: ["a", "b"] }, { items: ["a"] }], b: [{ items: ["b"] }] }

Implementation

const groupByMany = <K extends string, V>(
  func: (el: V) => K[] | undefined
) => (acc: Record<K, V[]>, el: V): Record<K, V[]> => {
  const groupNames = func(el) || [];
  groupNames.forEach(key => {
    if (!acc[key]) acc[key] = [];
    acc[key].push(el);
  });
  return acc;
}

groupByProperty

groupByProperty: <K extends keyof V, V extends { [key: string]: any; }>(key: K) => (acc: Record<V[K], V[]>, el: V) => Record<V[K], V[]>

Use with: reduce

Given a property name, returns an object containing the elements grouped by the values for that property. A second argument must be passed to reduce . For javascript an empty object is enough. For typescript an object with properties or a type cast may be required.

[{ name: "Jane" }, { name: "John" }].reduce(
  groupByProperty("name"),
  {}
); // Returns { Jane: [{ name: "Jane" }], John: [{ name: "John" }] }

Implementation

const groupByProperty = <
  K extends keyof V,
  V extends { [key: string]: any }
>(
  key: K
) => (acc: Record<V[K], V[]>, el: V): Record<V[K], V[]> => {
  const groupName = el[key];
  if (!groupName) return acc;
  if (!acc[groupName]) acc[groupName] = [];
  acc[groupName].push(el);
  return acc;
}

has

has: <TObject extends object, TKey extends keyof TObject>(...keys: TKey[]) => (object: TObject) => object is TObject & HasProperties<TObject, TKey>

Use with: find , filter

Returns true for elements where element[key] for all provided keys is defined. This is useful when properties are needed but optional in the element type.

Known limitations: Type inference doesn't always work when list elements have an inferred type.

type Person = { name?: string };
const people: Person[] = [{ name: "John" }, {}];
people.filter(has("name")); // Returns [{ name: "a" }]

Implementation

const has = <TObject extends object, TKey extends keyof TObject>(
  ...keys: TKey[]
) => (object: TObject): object is TObject & HasProperties<TObject, TKey> =>
  keys.every(key => isDefined(object[key]))

intersection

intersection: <T>(list: T[]) => (el: T) => boolean

Use with: filter

Returns a list of elements that are present in both lists

[1, 2, 3].filter(intersection([2, 3, 4])); // Returns [2, 3]

Implementation

const intersection = <T>(list: T[]) => (el: T) =>
  findIndex(list, a => a === el) !== -1

intersectionBy

intersectionBy: <T>(func: (el: T) => unknown, list: T[]) => (el: T) => boolean

Use with: filter

Returns a list of elements that are present in both lists compared by running func on elements in both lists

[{ a: 1 }, { a: 2 }, { a: 3 }]
  .filter(intersectionBy(el => el.a, [{ a: 2 }, { a: 3 }, { a: 4 }]));
  // Returns [{ a: 2 }, { a: 3 }]

Implementation

const intersectionBy = <T>(func: (el: T) => unknown, list: T[]) => (
  el: T
) => findIndex(list, a => func(a) === func(el)) !== -1

intersectionByProperty

intersectionByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey, list: TObject[]) => (el: TObject) => boolean

Use with: filter

Returns a list of elements that are present in both lists compared at key

[{ a: 1 }, { a: 2 }, { a: 3 }]
  .filter(intersectionByProperty("a", [{ a: 2 }, { a: 3 }, { a: 4 }]));
  // Returns [{ a: 2 }, { a: 3 }]

Implementation

const intersectionByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey,
  list: TObject[]
) => intersectionBy(get(key), list)

is

is: <T>(value: T) => (el: T) => boolean

Use with: find , filter

Returns true for elements that are equal to value

[1,2,3].find(is(1)); // Returns 1
[1,1,2].filter(is(1)); // Returns [1, 1]

Implementation

const is = <T>(value: T) => (el: T) => el === value

isBy

isBy: <T, U>(func: (el: T) => U, value: U) => (el: T) => boolean

Use with: find , filter

Returns true for elements where func(element) equals value

[{ a: 1 }, { a: 2 }].find(isBy(el => el.a, 2)); // Returns { a: 2 }
[{ a: 1 }, { a: 2 }].filter(isBy(el => el.a, 2)); // Returns [{ a: 2 }]

Implementation

const isBy = <T, U>(func: (el: T) => U, value: U) => (el: T) =>
  func(el) === value

isDefined

isDefined: <T>(x: T) => x is NonNullable<T>

Use with: filter

Remove elements that are undefined or null

[1, null, undefined, 2].filter(isDefined); // Returns [1, 2]

Implementation

const isDefined = <T>(x: T): x is NonNullable<T> =>
  x !== undefined && x !== null

isOneOf

isOneOf: <T>(list: T[]) => (el: T) => boolean

Use with: find , filter

Alias for intersection . Returns true for elements that exist in the provided list

[1,1,2,2,3].filter(isOneOf([2,3])); // Returns [2, 2, 3]

Implementation

const isOneOf = intersection

isOneOfBy

isOneOfBy: <T, U>(func: (el: T) => U, list: U[]) => (el: T) => boolean

Use with: find , filter

Returns true for elements where func(element) exists in list

[{ a: 1 }, { a: 2 }, { a: 3 }].find(isOneOfBy(el => el.a, [2, 3]));
// ^ Returns { a: 2 }
[{ a: 1 }, { a: 2 }, { a: 3 }].filter(isOneOfBy(el => el.a, [2, 3]));
// ^ Returns [{ a: 2 }, { a: 3 }]

Implementation

const isOneOfBy = <T, U>(func: (el: T) => U, list: U[]) => (el: T) =>
  findIndex(list, a => a === func(el)) !== -1

isnt

isnt: <T>(value: T) => (el: T) => boolean

Use with: find , filter

Returns true for elements that are not equal to value

[1,2,3].find(isnt(1)); // Returns 2
[1,2,2].filter(isnt(1)); // Returns [2,2]

Implementation

const isnt = <T>(value: T) => (el: T) => el !== value

isntBy

isntBy: <T, U>(func: (el: T) => U, value: U) => (el: T) => boolean

Use with: find , filter

Returns true for elements where func(element) does not equal value

[{ a: 1 }, { a: 2 }].find(isntBy(el => el.a, 2)); // Returns { a: 1 }
[{ a: 1 }, { a: 2 }].filter(isntBy(el => el.a, 2)); // Returns [{ a: 1 }]

Implementation

const isntBy = <T, U>(func: (el: T) => U, value: U) => (el: T) =>
  func(el) !== value

isntOneOf

isntOneOf: <T>(list: T[]) => (el: T) => boolean

Use with: find , filter

Alias for exclude . Returns true for elements that do not exist in the provided list

[1,1,2,2,3].filter(isntOneOf([2,3])); // Returns [1, 1]

Implementation

const isntOneOf = exclude

isntOneOfBy

isntOneOfBy: <T, U>(func: (el: T) => U, list: U[]) => (el: T) => boolean

Use with: find , filter

Returns true for elements where func(element) exists in list

[{ a: 1 }, { a: 2 }, { a: 3 }].find(isntOneOfBy(el => el.a, [2, 3]));
// ^ Returns { a: 1 }
[{ a: 1 }, { a: 2 }, { a: 3 }].filter(isntOneOfBy(el => el.a, [2, 3]));
// ^ Returns [{ a: 1 }]

Implementation

const isntOneOfBy = <T, U>(func: (el: T) => U, list: U[]) => (el: T) =>
  findIndex(list, a => a === func(el)) === -1

max

max: (acc: number, el: number) => number

Use with: reduce

Returns the largest value in the list

[1,2,3,4].reduce(max); // Returns 4

Implementation

const max = (acc: number, el: number) => Math.max(acc, el)

maxBy

maxBy: <T>(func: (el: T) => number) => (acc: T, el: T) => T

Use with: reduce

Returns the largest element by comparing func(element)

[{ a: 1 }, { a: 2 }, { a: 3 }].reduce(maxBy(el => el.a)); // Returns { a: 3 }

Implementation

const maxBy = <T>(func: (el: T) => number) => (acc: T, el: T) =>
  func(el) > func(acc) ? el : acc

maxByProperty

maxByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey) => (acc: TObject, el: TObject) => TObject

Use with: reduce

Returns the largest element by comparing element[key]

[{ a: 1 }, { a: 2 }, { a: 3 }].reduce(maxByProperty("a")); // Returns { a: 3 }

Implementation

const maxByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey
) => (acc: TObject, el: TObject) => (el[key] > acc[key] ? el : acc)

min

min: (acc: number, el: number) => number

Use with: reduce

Returns the smallest value in the list

[1,2,3,4].reduce(min); // Returns 1

Implementation

const min = (acc: number, el: number) => Math.min(acc, el)

minBy

minBy: <T>(func: (el: T) => number) => (acc: T, el: T) => T

Use with: reduce

Returns the smallest element by comparing func(element)

[{ a: 1 }, { a: 2 }, { a: 3 }].reduce(minBy(el => el.a)); // Returns { a: 1 }

Implementation

const minBy = <T>(func: (el: T) => number) => (acc: T, el: T) =>
  func(el) < func(acc) ? el : acc

minByProperty

minByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey) => (acc: TObject, el: TObject) => TObject

Use with: reduce

Returns the smallest element by comparing element[key]

[{ a: 1 }, { a: 2 }, { a: 3 }].reduce(minByProperty("a")); // Returns { a: 1 }

Implementation

const minByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey
) => (acc: TObject, el: TObject) => (el[key] < acc[key] ? el : acc)

or

or: <T>(fallback: NonNullable<T>) => (x: T) => NonNullable<T>

Use with: map

Replaces list elements that are undefined or null with fallback

[1, null, undefined, 2].map(or(0)); // Returns [1, 0, 0, 2]

Implementation

const or = <T>(fallback: NonNullable<T>) => (x: T): NonNullable<T> =>
  isDefined(x) ? x : fallback

partition

partition: <T>(func: (el: T) => boolean) => (acc: T[][], el: T) => T[][]

Use with: reduce

Splits the input list into two lists. The first list contains elements for which the given function returned true , the second contains elements for which the function returned false .

[{ age: 10 }, { age: 80 }].reduce(partition(el => el.age > 30), []);
// Returns [[{ age: 80 }], [{ age: 10 }]]

Implementation

const partition = <T>(func: (el: T) => boolean) => (
  acc: T[][],
  el: T
) => {
  const a0 = acc[0] || [],
    a1 = acc[1] || [];
  if (func(el)) a0.push(el);
  else a1.push(el);
  return [a0, a1];
}

propertyIs

propertyIs: <TObject extends object, TKey extends keyof TObject>(key: TKey, value: TObject[TKey]) => (el: TObject) => boolean

Use with: find , filter

Returns true for elements where element[key] equals value

[{ a: 1 }, { a: 2 }].find(propertyIs("a", 2)); // Returns { a: 2 }
[{ a: 1 }, { a: 2 }].filter(propertyIs("a", 2)) // Returns [{ a: 2 }]

Implementation

const propertyIs = <TObject extends object, TKey extends keyof TObject>(
  key: TKey,
  value: TObject[TKey]
) => isBy(get(key), value)

propertyIsOneOf

propertyIsOneOf: <TObject extends object, TKey extends keyof TObject>(key: TKey, list: TObject[TKey][]) => (el: TObject) => boolean

Use with: find , filter

Returns true for elements where element[key] exists in list

[{ a: 1 }, { a: 2 }, { a: 3 }].find(propertyIsOneOf("a", [2, 3]));
// ^ Returns { a: 2 }
[{ a: 1 }, { a: 2 }, { a: 3 }].filter(propertyIsOneOf("a", [2, 3]));
// ^ Returns [{ a: 2 }, { a: 3 }]

Implementation

const propertyIsOneOf = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey,
  list: TObject[TKey][]
) => isOneOfBy(get(key), list)

propertyIsnt

propertyIsnt: <TObject extends object, TKey extends keyof TObject>(key: TKey, value: TObject[TKey]) => (el: TObject) => boolean

Use with: find , filter

Returns true for elements where element[key] does not equal value

[{ a: 1 }, { a: 2 }].find(propertyIsnt("a", 2)); // Returns { a: 1 }
[{ a: 1 }, { a: 2 }].filter(propertyIsnt("a", 2)); // Returns [{ a: 1 }]

Implementation

const propertyIsnt = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey,
  value: TObject[TKey]
) => isntBy(get(key), value)

propertyIsntOneOf

propertyIsntOneOf: <TObject extends object, TKey extends keyof TObject>(key: TKey, list: TObject[TKey][]) => (el: TObject) => boolean

Use with: find , filter

Returns true for elements where element[key] exists in list

[{ a: 1 }, { a: 2 }, { a: 3 }].find(propertyIsntOneOf("a", [2, 3]));
// ^ Returns { a: 1 }
[{ a: 1 }, { a: 2 }, { a: 3 }].filter(propertyIsntOneOf("a", [2, 3]));
// ^ Returns [{ a: 1 }]

Implementation

const propertyIsntOneOf = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey,
  list: TObject[TKey][]
) => isntOneOfBy(get(key), list)

sum

sum: (acc: number, element: number) => number

Use with: reduce

Sum a list of numbers

[1, 2, 3].reduce(sum); // Returns 6

Implementation

const sum = (acc: number, element: number) => acc + element

sumBy

sumBy: {
  <T>(func: (el: T) => number): (acc: number, el: T) => number;
  <T>(func: (el: number) => number): (acc: number, el: number) => number;
}

Use with: reduce

Sums the values by applying func to elements. If the list elements aren't numbers, a number must be passed as the second argument to reduce .

[{ a: 1 }, { a: 2 }].reduce(sumBy(el => el.a), 0); // Returns 3
[1.5, 2.5].reduce(sumBy(Math.floor)); // Returns 3

Implementation

export function sumBy<T>(func: (el: T | number) => number) {
  return (acc: number, el: T | number) =>
    typeof el === "number" ? func(acc) + func(el) : acc + func(el);
}

sumByProperty

sumByProperty: <TObject extends { [key: string]: number; }, TKey extends keyof TObject>(key: TKey) => (acc: number, el: TObject) => number

Use with: reduce

Sums the values of element[key] for all elements. A number must be passed to the second argument of reduce .

[{ a: 1 }, { a: 2 }].reduce(sumByProperty('a'), 0); // Returns 3

Implementation

const sumByProperty = <
  TObject extends { [key: string]: number },
  TKey extends keyof TObject
>(
  key: TKey
) => (acc: number, el: TObject) => acc + el[key]

unique

unique: (el: unknown, index: number, list: unknown[]) => boolean

Use with: filter

Removes duplicates from list

[1,1,1,2].filter(unique); // Returns [1, 2]

Implementation

const unique = uniqueBy(el => el)

uniqueBy

uniqueBy: <T>(func: (el: T) => unknown) => (el: T, index: number, list: T[]) => boolean

Use with: filter

Removes duplicates compared by func(element)

[{ a: 1 }, { a : 1 }].filter(uniqueBy(el => el.a)); // Returns [{ a: 1 }]

Implementation

const uniqueBy = <T>(func: (el: T) => unknown) => (
  el: T,
  index: number,
  list: T[]
) => index === findIndex(list, t => func(t) === func(el))

uniqueByProperty

uniqueByProperty: <TObject extends object, TKey extends keyof TObject>(key: TKey) => (el: TObject, index: number, list: TObject[]) => boolean

Use with: filter

Removes duplicates compared by element[key]

[{ a: 1 }, { a: 1 }].filter(uniqueByProperty('a')); // Return [{ a: 1 }]

Implementation

const uniqueByProperty = <
  TObject extends object,
  TKey extends keyof TObject
>(
  key: TKey
) => uniqueBy<TObject>(get(key))

FAQs

Last updated on 21 Jan 2021

Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc