Code Monkey home page Code Monkey logo

just's Introduction

Just

A library of zero-dependency npm modules that do just one thing. A guilt-free alternative to those bulkier utility libraries. Ideal for PWA development or whenever bytes are precious.

Build status

We welcome contributions. Please follow our contribution guidelines.

Try 🍦

A REPL for every utility (powered by RunKit)

Read πŸ“š

ES and CJS modules available for every utility

All packages support ES module or Common JS syntax without requiring transpilation

// esm (node / bundler)
import clone from 'just-clone';

// esm (native browser code)
import clone from './node_modules/just-clone/index.mjs';

// cjs
const clone = require('just-clone');

TypeScript

We've now added TypeScript definitions and tests for every Just utility

Browser/Platform Support πŸ’»

Most utilities still work with any platform that supports ES5, but these are the earliest versions guranteed to support every utility. For guidance, any platform that supports spread in array literals will work with Just.

Chrome Safari Firefox Edge Node Mobile Safari Android Chrome
46 8 16 12 6.0 8 46

The Modules πŸ“¦

Collections

source

🍦 Try it

npm install just-diff
yarn add just-diff

Return an object representing the difference between two other objects Pass converter to format as http://jsonpatch.com

import {diff} from 'just-diff';

const obj1 = {a: 4, b: 5};
const obj2 = {a: 3, b: 5};
const obj3 = {a: 4, c: 5};

diff(obj1, obj2);
[
  { "op": "replace", "path": ['a'], "value": 3 }
]

diff(obj2, obj3);
[
  { "op": "remove", "path": ['b'] },
  { "op": "replace", "path": ['a'], "value": 4 }
  { "op": "add", "path": ['c'], "value": 5 }
]

// using converter to generate jsPatch standard paths
import {diff, jsonPatchPathConverter} from 'just-diff'
diff(obj1, obj2, jsonPatchPathConverter);
[
  { "op": "replace", "path": '/a', "value": 3 }
]

diff(obj2, obj3, jsonPatchPathConverter);
[
  { "op": "remove", "path": '/b' },
  { "op": "replace", "path": '/a', "value": 4 }
  { "op": "add", "path": '/c', "value": 5 }
]

// arrays
const obj4 = {a: 4, b: [1, 2, 3]};
const obj5 = {a: 3, b: [1, 2, 4]};
const obj6 = {a: 3, b: [1, 2, 4, 5]};

diff(obj4, obj5);
[
  { "op": "replace", "path": ['a'], "value": 3 }
  { "op": "replace", "path": ['b', 2], "value": 4 }
]

diff(obj5, obj6);
[
  { "op": "add", "path": ['b', 3], "value": 5 }
]

// nested paths
const obj7 = {a: 4, b: {c: 3}};
const obj8 = {a: 4, b: {c: 4}};
const obj9 = {a: 5, b: {d: 4}};

diff(obj7, obj8);
[
  { "op": "replace", "path": ['b', 'c'], "value": 4 }
]

diff(obj8, obj9);
[
  { "op": "replace", "path": ['a'], "value": 5 }
  { "op": "remove", "path": ['b', 'c']}
  { "op": "add", "path": ['b', 'd'], "value": 4 }
]

source

🍦 Try it

npm install just-diff-apply
yarn add just-diff-apply

Apply a diff object to an object. Pass converter to apply a http://jsonpatch.com standard patch

  import {diffApply} from 'just-diff-apply';

  const obj1 = {a: 3, b: 5};
  diffApply(obj1,
    [
      { "op": "remove", "path": ['b'] },
      { "op": "replace", "path": ['a'], "value": 4 },
      { "op": "add", "path": ['c'], "value": 5 }
    ]
  );
  obj1; // {a: 4, c: 5}

  const obj2 = {a: 3, b: 5};
  diffApply(obj2,
    [
      { "op": "move", "from": ['a'], "path": ['c']},
    ]
  );
  obj2; // {b: 5, c: 3}

  // using converter to apply jsPatch standard paths
  // see http://jsonpatch.com
  import {diffApply, jsonPatchPathConverter} from 'just-diff-apply'
  const obj3 = {a: 3, b: 5};
  diffApply(obj3, [
    { "op": "remove", "path": '/b' },
    { "op": "replace", "path": '/a', "value": 4 }
    { "op": "add", "path": '/c', "value": 5 }
  ], jsonPatchPathConverter);
  obj3; // {a: 4, c: 5}

  // arrays (array key can be string or numeric)
  const obj4 = {a: 4, b: [1, 2, 3]};
  diffApply(obj4, [
    { "op": "replace", "path": ['a'], "value": 3 }
    { "op": "replace", "path": ['b', 2], "value": 4 }
    { "op": "add", "path": ['b', 3], "value": 9 }
  ]);
  obj4; // {a: 3, b: [1, 2, 4, 9]}

  // nested paths
  const obj5 = {a: 4, b: {c: 3}};
  diffApply(obj5, [
    { "op": "replace", "path": ['a'], "value": 5 }
    { "op": "remove", "path": ['b', 'c']}
    { "op": "add", "path": ['b', 'd'], "value": 4 }
  ]);
  obj5; // {a: 5, b: {d: 4}}

source

🍦 Try it

npm install just-compare
yarn add just-compare

Compare two collections

import compare from 'just-compare';

// primitives: value1 === value2
// functions: value1.toString == value2.toString
// arrays: if length, sequence and values of properties are identical
// objects: if length, names and values of properties are identical
compare([1, [2, 3]], [1, [2, 3]]); // true
compare([1, [2, 3], 4], [1, [2, 3]]); // false
compare({a: 2, b: 3}, {a: 2, b: 3}); // true
compare({a: 2, b: 3}, {b: 3, a: 2}); // true
compare({a: 2, b: 3, c: 4}, {a: 2, b: 3}); // false
compare({a: 2, b: 3}, {a: 2, b: 3, c: 4}); // false
compare([1, [2, {a: 4}], 4], [1, [2, {a: 4}]]); // false
compare([1, [2, {a: 4}], 4], [1, [2, {a: 4}], 4]); // true
compare(NaN, NaN); // true

source

🍦 Try it

npm install just-clone
yarn add just-clone

Deep copies objects, arrays, maps and sets

// Deep copies objects and arrays, doesn't clone functions

import clone from 'just-clone';

var arr = [1, 2, 3];
var subObj = { aa: 1 };
var obj = { a: 3, b: 5, c: arr, d: subObj };
var objClone = clone(obj);
arr.push(4);
objClone.d.bb = 2;
obj; // {a: 3, b: 5, c: [1, 2, 3, 4], d: {aa: 1}}
objClone; // {a: 3, b: 5, c: [1, 2, 3], d: {aa: 1, bb: 2}}

source

🍦 Try it

npm install just-pluck-it
yarn add just-pluck-it

Pluck a property from each member of a collection

import pluck from 'just-pluck-it';

pluck([{a:1, b:2}, {a:4, b:3}, {a:2, b:5}], 'a'); // [1, 4, 2]
pluck({x: {a:1, b:2}, y: {a:4, b:3}, z: {a:2, b:5}}, 'a'); // {x: 1, y: 4, z: 2}

source

🍦 Try it

npm install just-flush
yarn add just-flush

Returns a copy of an array or object with null/undefined members removed

import flush from 'just-flush';

flush([1, undefined, 2, null, 3, NaN, 0]); // [1, 2, 3, NaN, 0]
flush([true, null, false, true, [null], undefined]); // [true, false, true, [null]]
flush({a: 2, b: null, c: 4, d: undefined}); // {a: 2, c: 4}
flush('something'); // undefined
flush(); // undefined

Objects

source

🍦 Try it

npm install just-extend
yarn add just-extend

Extend an object

import extend from 'just-extend';

var obj = {a: 3, b: 5};
extend(obj, {a: 4, c: 8}); // {a: 4, b: 5, c: 8}
obj; // {a: 4, b: 5, c: 8}

var obj = {a: 3, b: 5};
extend({}, obj, {a: 4, c: 8}); // {a: 4, b: 5, c: 8}
obj; // {a: 3, b: 5}

var arr = [1, 2, 3];
var obj = {a: 3, b: 5};
extend(obj, {c: arr}); // {a: 3, b: 5, c: [1, 2, 3]}
arr.push(4);
obj; // {a: 3, b: 5, c: [1, 2, 3, 4]}

var arr = [1, 2, 3];
var obj = {a: 3, b: 5};
extend(true, obj, {c: arr}); // {a: 3, b: 5, c: [1, 2, 3]}
arr.push(4);
obj; // {a: 3, b: 5, c: [1, 2, 3]}

extend({a: 4, b: 5}); // {a: 4, b: 5}
extend({a: 4, b: 5}, 3); {a: 4, b: 5}
extend({a: 4, b: 5}, true); {a: 4, b: 5}
extend('hello', {a: 4, b: 5}); // throws
extend(3, {a: 4, b: 5}); // throws

source

🍦 Try it

npm install just-merge
yarn add just-merge

Shallow assign. Like just-extend but without deep copy option.

import merge from 'just-merge';

let obj = {a: 3, b: 5};
merge(obj, {a: 4, c: 8}); // {a: 4, b: 5, c: 8}
obj; // {a: 4, b: 5, c: 8}

let obj = {a: 3, b: 5};
merge({}, obj, {a: 4, c: 8}); // {a: 4, b: 5, c: 8}
obj; // {a: 3, b: 5}

let arr = [1, 2, 3];
let obj = {a: 3, b: 5};
merge(obj, {c: arr}); // {a: 3, b: 5, c: [1, 2, 3]}
arr.push[4];
obj; // {a: 3, b: 5, c: [1, 2, 3, 4]}

merge({a: 4, b: 5}); // {a: 4, b: 5}
merge(3, {a: 4, b: 5}); // throws
merge({a: 4, b: 5}, 3); // throws
merge({a: 4, b: 5}, {b: 4, c: 5}, 'c'); // throws

source

🍦 Try it

npm install just-values
yarn add just-values

Return property values as an array

const values = require('just-values');

values({a: 4, c: 8}); // [4, 8]
values({a: {aa: 2}, b: {bb: 4}}); // [{aa: 2}, {bb: 4}]
values({}); // []
values([1, 2, 3]); // [1, 2, 3]
values(function(a, b) {return a + b;}); // []
values(new String('hello')); // ['h', 'e', 'l', 'l', 'o']
values(1); // throws exception
values(true); // throws exception
values(undefined); // throws exception
values(null); // throws exception

source

🍦 Try it

npm install just-entries
yarn add just-entries

Return object entries as an array of [key, value] pairs

import entries from 'just-entries';

// Object:
entries({c: 8, a: 4}); // [['c', 8], ['a', 4]]
entries({b: {bb: 4}, a: {aa: 2}}); // [['b', {bb: 4}], ['a', {aa: 2}]]
entries({}); // []

// Array:
entries([{c: 8}, {a: 4}]); // [[0, {c: 8}], [1, {a: 4}]]
entries(['Γ€', 'mauvais', 'ouvrier', 'point', 'de', 'bon', 'outil'])
// [[0, 'Γ€'], [1, 'mauvais'] ... [6, 'outil']]
entries([]); // []

source

🍦 Try it

npm install just-pick
yarn add just-pick

Copy an object but with only the specified keys

import pick from 'just-pick';

var obj = { a: 3, b: 5, c: 9 };
pick(obj, ['a', 'c']); // {a: 3, c: 9}
pick(obj, 'a', 'c'); // {a: 3, c: 9}
pick(obj, ['a', 'b', 'd']); // {a: 3, b: 5}
pick(obj, ['a', 'a']); // {a: 3}

source

🍦 Try it

npm install just-omit
yarn add just-omit

Copy an object but omit the specified keys

import omit from 'just-omit';

var obj = {a: 3, b: 5, c: 9};
omit(obj, ['a', 'c']); // {b: 5}
omit(obj, 'a', 'c'); // {b: 5}
omit(obj, ['a', 'b', 'd']); // {c: 9}
omit(obj, ['a', 'a']); // {b: 5, c: 9}

source

🍦 Try it

npm install just-is-empty
yarn add just-is-empty

Return true if object has no enumerable key values

import isEmpty from 'just-is-empty';
 isEmpty({a: 3, b: 5}) // false
 isEmpty([1, 2]) // false
 isEmpty(new Set([1, 2, 2])) // false
 isEmpty((new Map()).set('a', 2)) // false
 isEmpty({}) // true
 isEmpty([]) // true
 isEmpty(new Set()) // true
 isEmpty(new Map()) // true
 isEmpty('abc') // false
 isEmpty('') // true
 isEmpty(0) // true
 isEmpty(1) // true
 isEmpty(true) // true
 isEmpty(Symbol('abc')); // true
 isEmpty(//); // true
 isEmpty(new String('abc')); // false
 isEmpty(new String('')); // true
 isEmpty(new Boolean(true)); // true
 isEmpty(null) // true
 isEmpty(undefined) // true

source

🍦 Try it

npm install just-is-circular
yarn add just-is-circular

Return true if object has a circular reference NOTE: not supported in IE or microsoft edge

import isCircular from 'just-is-circular';
const a = {};
a.b = a;
isCircular(a); // true

const a = {};
a.b = {
  c: a
};
isCircular(a); // true

const a = {};
a.b = {
  c: 4
};
isCircular(a); // false

const a = [];
a.push(a);
isCircular(a); // true

isCircular({}); // false
isCircular('hi'); // false
isCircular(undefined); // false

source

🍦 Try it

npm install just-is-primitive
yarn add just-is-primitive

Determine if a value is a primitive value

import isPrimitive from 'just-is-primitive';
isPrimitive('hi') // true
isPrimitive(3) // true
isPrimitive(true) // true
isPrimitive(false) // true
isPrimitive(null) // true
isPrimitive(undefined) // true
isPrimitive(Symbol()) // true
isPrimitive({}) // false
isPrimitive([]) // false
isPrimitive(function() {}) // false
isPrimitive(new Date()) // false
isPrimitive(/a/) // false

source

🍦 Try it

npm install just-filter-object
yarn add just-filter-object

Filter an object

import filter from 'just-filter';

// returns a new object containing those original properties for which the predicate returns truthy
filter({a: 3, b: 5, c: 9}, (key, value) => value < 6); // {a: 3, b: 5}
filter({a1: 3, b1: 5, a2: 9}, (key, value) => key[0] == 'a'); // {a1: 3, a2: 9}
filter({a: 3, b: 5, c: null}, (key, value) => value); // {a: 3, b: 5}

source

🍦 Try it

npm install just-map-object
yarn add just-map-object

Map an object, passing key and value to predicates

import map from 'just-map-object';

// DEPRECATED: use just-map-values
map({a: 3, b: 5, c: 9}, (key, value) => value + 1); // {a: 4, b: 6, c: 10}
map({a: 3, b: 5, c: 9}, (key, value) => key); // {a: 'a', b: 'b', c: 'c'}
map({a: 3, b: 5, c: 9}, (key, value) => key + value); // {a: 'a3', b: 'b5', c: 'c9'}```

source

🍦 Try it

npm install just-map-values
yarn add just-map-values

Map an object, predicate updates values, receives (value, key, object)

import map from 'just-map-values';

// predicate updates values, receives (value, key, obj)
map({a: 3, b: 5, c: 9}, (value) => value + 1); // {a: 4, b: 6, c: 10}
map({a: 3, b: 5, c: 9}, (value, key) => value + key); // {a: 3a, b: 5b, c: 9c}
map({a: 3, b: 5, c: 9}, (value, key, obj) => obj.b); // {a: 5, b: 5, c: 5}

source

🍦 Try it

npm install just-map-keys
yarn add just-map-keys

Map an object, predicate updates keys, receives (value, key, object)

import map from 'just-map-keys';

// predicate updates keys, receives (value, key, object)
map({a: 'cow', b: 'sheep', c: 'pig'}, (value) => value);
  // {cow: 'cow', sheep: 'sheep', pig: 'pig'}
map([4, 5, 6], (value, key) => key + 1); // {1: 4, 2: 5, 3: 6}
map({a: 3, b: 5, c: 9}, (value, key) => key + value); // {a3: 3, b5: 5, c9: 9}
map({a: 3, b: 5, c: 9}, (value, key, obj) => obj.b + value + key);
  // {'8a': 3, '10b': 5, '14c': 9}

source

🍦 Try it

npm install just-deep-map-values
yarn add just-deep-map-values

Returns an object with values at all depths mapped according to the provided function

import deepMapValues from 'just-deep-map-values';

const squareFn = (number) => number * number;
deepMapValues({ a: 1, b: { c: 2, d: { e: 3 } } }, squareFn); // => { a: 1, b: { c: 4, d: { e: 9 } } }

source

🍦 Try it

npm install just-reduce-object
yarn add just-reduce-object

Reduce an object

import reduce from 'just-reduce-object';

// applies a function against an accumulator and each key-value pairs of the object
// to reduce it to a single value
reduce({a: 3, b: 5, c: 9}, (acc, key, value, index, keys) => {
  acc[value] = key;
  return acc;
}, {}); // {3: 'a', 5: 'b', 9: 'c'}

reduce({a: 3, b: 5, c: 9}, (acc, key, value, index, keys) => {
  acc += value;
  return acc;
}); // 17

source

🍦 Try it

npm install just-safe-get
yarn add just-safe-get

Get value at property, don't throw if parent is undefined

import get from 'just-safe-get';

const obj = {a: {aa: {aaa: 2}}, b: 4};

get(obj, 'a.aa.aaa'); // 2
get(obj, ['a', 'aa', 'aaa']); // 2

get(obj, 'b.bb.bbb'); // undefined
get(obj, ['b', 'bb', 'bbb']); // undefined

get(obj.a, 'aa.aaa'); // 2
get(obj.a, ['aa', 'aaa']); // 2

get(obj.b, 'bb.bbb'); // undefined
get(obj.b, ['bb', 'bbb']); // undefined

get(obj.b, 'bb.bbb', 5); // 5
get(obj.b, ['bb', 'bbb'], true); // true

get(null, 'a'); // undefined
get(undefined, ['a']); // undefined

get(null, 'a', 42); // 42
get(undefined, ['a'], 42); // 42

const obj = {a: {}};
const sym = Symbol();
obj.a[sym] = 4;
get(obj.a, sym); // 4

source

🍦 Try it

npm install just-safe-set
yarn add just-safe-set

Set value at property, create intermediate properties if necessary

import set from 'just-safe-set';

const obj1 = {};
set(obj1, 'a.aa.aaa', 4); // true
obj1; // {a: {aa: {aaa: 4}}}

const obj2 = {};
set(obj2, ['a', 'aa', 'aaa'], 4); // true
obj2; // {a: {aa: {aaa: 4}}}

const obj3 = {a: {aa: {aaa: 2}}};
set(obj3, 'a.aa.aaa', 3); // true
obj3; // {a: {aa: {aaa: 3}}}

const obj5 = {a: {}};
const sym = Symbol();
set(obj5.a, sym, 7); // true
obj5; // {a: {Symbol(): 7}}

source

🍦 Try it

npm install just-typeof
yarn add just-typeof

Type inferer

import typeOf from 'just-typeof';

typeOf({}); // 'object'
typeOf([]); // 'array'
typeOf(function() {}); // 'function'
typeOf(/a/); // 'regexp'
typeOf(new Date()); // 'date'
typeOf(null); // 'null'
typeOf(undefined); // 'undefined'
typeOf('a'); // 'string'
typeOf(1); // 'number'
typeOf(true); // 'boolean'

source

🍦 Try it

npm install just-flip-object
yarn add just-flip-object

Flip the keys and values

import flip from 'just-flip-object';

// flip the key and value
flip({a: 'x', b: 'y', c: 'z'}); // {x: 'a', y: 'b', z: 'c'}
flip({a: 1, b: 2, c: 3}); // {'1': 'a', '2': 'b', '3': 'c'}
flip({a: false, b: true}); // {false: 'a', true: 'b'}

source

🍦 Try it

npm install just-has
yarn add just-has

Return a boolen indicating the existence of a deep property, don't throw if parent is undefined

import has from 'just-has';

const obj = {a: {aa: {aaa: 2}}, b: 4};

has(obj, 'a.aa.aaa'); // true
has(obj, ['a', 'aa', 'aaa']); // true

has(obj, 'b.bb.bbb'); // false
has(obj, ['b', 'bb', 'bbb']); // false

has(obj.a, 'aa.aaa'); // true
has(obj.a, ['aa', 'aaa']); // true

has(obj.b, 'bb.bbb'); // false
has(obj.b, ['bb', 'bbb']); // false

has(null, 'a'); // false
has(undefined, ['a']); // false

const obj = {a: {}};
const sym = Symbol();
obj.a[sym] = 4;
has(obj.a, sym); // true

Arrays

source

🍦 Try it

npm install just-cartesian-product
yarn add just-cartesian-product

Takes an input of an array of arrays and returns their Cartesian product.

import cartesianProduct from 'just-cartesian-product';

cartesianProduct([[1, 2], ['a', 'b']]); // [[1, 'a'], [1, 'b'], [2, 'a'], [2, 'b']]
cartesianProduct([[1, 2], ['a', 'b', 'c']]); // [[1, 'a'], [1, 'b'], [1, 'c'], [2, 'a'], [2, 'b'], [2, 'c']]
cartesianProduct([]); // []
cartesianProduct(); // throws

source

🍦 Try it

npm install just-unique
yarn add just-unique

Dedupes an array

import unique from 'just-unique';

unique([1, 2, 3, 2, 3, 4, 3, 2, 1, 3]); // [1, 2, 3, 4]

var a = {a: 3};
var b = {b: 4};
var c = {c: 5};
unique([a, a, b, c, b]); // [a, b, c]

unique([1, '1', 2, '2', 3, 2]); // [1, '1', 2, '2', 3]

// declaring sorted array for performance
unique([1, 1, '1', 2, 2, 5, '5', '5'], true); // [1, '1', 2, 5, '6']

// declaring strings array for performance
unique(['a', 'c', 'b', 'c', 'a'], false, true); // ['a', 'b', 'c']

source

🍦 Try it

npm install just-flatten-it
yarn add just-flatten-it

Return a flattened array

import flatten from 'just-flatten-it';

flatten([[1, [2, 3]], [[4, 5], 6, 7, [8, 9]]]);
// [1, 2, 3, 4, 5, 6, 7, 8, 9]

flatten([[1, [2, 3]], [[4, 5], 6, 7, [8, 9]]], 1);
// [1, [2, 3], [[4, 5], 6, 7, [8, 9]]]

source

🍦 Try it

npm install just-index
yarn add just-index

Return an object from an array, keyed by the value at the given id

import index from 'just-index';

index([{id: 'first', val: 1}, {id: 'second', val: 2}], 'id');
// {first: {id: 'first', val: 1}, second: {id: 'second', val: 2}}
index([{id: 'first', val: 1}, null], 'id'); // {first: {id: 'first', val: 1}}
index([], 'id'); // {}
index([], null); // undefined
index({}, 'id'); // undefined

source

🍦 Try it

npm install just-insert
yarn add just-insert

Inserts a sub-array into an array starting at the given index. Returns a copy

import insert from 'just-insert';

insert([1, 2, 5, 6], ['a', 'c', 'e'], 2); // [1, 2, 'a', 'c', 'e', 5, 6]
insert([1, 2, 5, 6], 'a', 2); // [1, 2, 'a', 5, 6]
insert([1, 2, 5, 6], ['a', 'c', 'e'], 0); // ['a', 'c', 'e', 1, 2, 5, 6]
insert([1, 2, 5, 6], ['a', 'c', 'e']); // ['a', 'c', 'e', 1, 2, 5, 6]

source

🍦 Try it

npm install just-intersect
yarn add just-intersect

Return the intersect of two arrays

import intersect from 'just-intersect';

intersect([1, 2, 5, 6], [2, 3, 5, 6]); // [2, 5, 6]
intersect([1, 2, 2, 4, 5], [3, 2, 2, 5, 7]); // [2, 5]  

source

🍦 Try it

npm install just-compact
yarn add just-compact

Returns a copy of an array with falsey values removed

import compact from 'just-compact';

compact([1, null, 2, undefined, null, NaN, 3, 4, false, 5]); // [1, 2, 3, 4, 5]
compact([1, 2, [], 4, {}]); // [1, 2, [], 4, {}]
compact([]); // []
compact({}); // throws

source

🍦 Try it

npm install just-last
yarn add just-last

Return the last member of an array

import last from 'just-last';

last([1, 2, 3, 4, 5]); // 5
last([{a: 1}, {b: 1}, {c: 1}]); // {c: 1}
last([true, false, [true, false]]); // [true, false]
last(); // undefined
last([]); // undefined
last(null); // undefined
last(undefined); // undefined

source

🍦 Try it

npm install just-tail
yarn add just-tail

Return all but the first element of an array

import tail from 'just-tail';

tail([1, 2, 3, 4, 5]); // [2, 3, 4, 5]
tail([{a: 1}, {b: 1}, {c: 1}]); // [{b: 1}, {c: 1}]
tail([true, false, [true, false]]); // [false, [true, false]]
tail([]); // []
tail(); // undefined
tail(null); // undefined
tail(undefined); // undefined

source

🍦 Try it

npm install just-random
yarn add just-random

Return a randomly selected element in an array

import random from 'just-random';

random([1, 2, 3]);
// one of [1, 2, 3], at random

source

🍦 Try it

npm install just-shuffle
yarn add just-shuffle

Return the elements of an array in random order

import shuffle from 'just-shuffle';

shuffle([1, 2, 3]); 
// array with original elements randomly sorted
shuffle([1, 2, 3], {shuffleAll: true}); 
// array with original elements randomly sorted and all in new postions
shuffle([]); // []
shuffle([1]); // [1]
shuffle(); // throws
shuffle(undefined); // throws
shuffle(null); // throws
shuffle({}); // throws

source

🍦 Try it

npm install just-split
yarn add just-split

Splits array into groups of n items each

import split from 'just-split';

split([]); // []
split([1, 2, 3, 4, 5]); // [[1, 2, 3, 4, 5]]
split([1, 2, 3, 4, 5, 6, 7, 8, 9], 3); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
split([1, 2, 3, 4, 5, 6, 7, 8, 9], '3'); // [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
split(['a', 'b', 'c', 'd', 'e'], 2); // [['a', 'b'], ['c', 'd'], ['e']]
split([1, 2, 3, 4, 5, 6, 7, 8], 3); // [[1, 2, 3], [4, 5, 6], [7, 8]]

source

🍦 Try it

npm install just-split-at
yarn add just-split-at

Splits an array into two at a given position

import splitAt from 'just-split-at';

splitAt([1, 2, 3, 4, 5], 2); // [[1, 2], [3, 4, 5]]
splitAt([{a: 1}, {b: 1}, {c: 1}], -1); // [[{a: 1}, {b: 1}], [{c: 1}]]
splitAt([], 2); // [[], []]
splitAt(null, 1); // throws
splitAt(undefined, 1); // throws

source

🍦 Try it

npm install just-order-by
yarn add just-order-by

Produces a new array, sorted in given order

import orderBy from 'just-order-by';

orderBy([10, 1, 5, 20, 15, 35, 30, 6, 8]); // [1, 5, 6, 8, 10, 15, 20, 30, 35]

orderBy(
  [
    { user: 'fabio', details: { city: 'Milan', age: 34 } },
    { user: 'max', details: { city: 'Munich', age: 29 } },
    { user: 'zacarias', details: { city: 'Sao Paulo', age: 44 } },
    { user: 'robert', details: { city: 'Manchester', age: 28 } },
    { user: 'max', details: { city: 'Zurich', age: 38 } },
  ],
  [
    {
      property(v) {
        return v.details.age;
      },
    },
  ]
);

/*
[
  {user: 'robert', age: 28},
  {user: 'max', age: 29},
  {user: 'fabio', age: 34},
  {user: 'klaus', age: 38},
  {user: 'zacarias', age: 44},
]
*/

orderBy(
  [
    {user: 'fabio', age: 34},
    {user: 'max', age: 29},
    {user: 'zacarias', age: 44},
    {user: 'robert', age: 28},
    {user: 'klaus', age: 38},
  ],
  [
    {
      property: 'user',
    },
  ]
);

/*
[
  {user: 'fabio', age: 34},
  {user: 'klaus', age: 38},
  {user: 'max', age: 29},
  {user: 'robert', age: 28},
  {user: 'zacarias', age: 44},
]
*/

orderBy(
  [
    { user: 'fabio', age: 34 },
    { user: 'max', age: 29 },
    { user: 'zacarias', age: 44 },
    { user: 'moris', age: 28 },
    { user: 'max', age: 38 },
  ],
  [
    {
      property: 'user',
      order: 'desc',
    },
    {
      property(v) {
        return v.age;
      },
    },
  ]
);

/*
[
  {
    user: 'zacarias',
    age: 44
  },
  {
    user: 'moris',
    age: 28
  },
  {
    user: 'max',
    age: 29
  },
  {
    user: 'max',
    age: 38
  },
  {
    user: 'fabio',
    age: 34
  }
]
*/

source

🍦 Try it

npm install just-sort-by
yarn add just-sort-by

Produces a new array, sorted in ascending order

import sortBy from 'just-sort-by';

sortBy([10, 1, 5, 20, 15, 35, 30, 6, 8]); // [1, 5, 6, 8, 10, 15, 20, 30, 35]

sortBy([
  {user: 'fabio', details: {city: "Milan", age: 34}},
  {user: 'max', details: {city: "Munich", age: 29}},
  {user: 'zacarias', details: {city: "Sao Paulo", age: 44}},
  {user: 'robert', details: {city: "Manchester", age: 28}},
  {user: 'klaus', details: {city: "Zurich", age: 38}},
], function(o) {
  return o.details.age;
});

/*
[
  {user: 'robert', age: 28},
  {user: 'max', age: 29},
  {user: 'fabio', age: 34},
  {user: 'klaus', age: 38},
  {user: 'zacarias', age: 44},
]
*/

sortBy([
  {user: 'fabio', age: 34},
  {user: 'max', age: 29},
  {user: 'zacarias', age: 44},
  {user: 'robert', age: 28},
  {user: 'klaus', age: 38},
], 'user');
/*
[
  {user: 'fabio', age: 34},
  {user: 'klaus', age: 38},
  {user: 'max', age: 29},
  {user: 'robert', age: 28},
  {user: 'zacarias', age: 44},
]
*/

source

🍦 Try it

npm install just-partition
yarn add just-partition

Elements satisfying predicate added to first array, remainder added to second

import partition from 'just-partition';

partition([1, 5, 2, 4, 3], n => n > 3); // [[5, 4],[1, 2, 3]]
partition(['a', 2, 3, '3'], x => typeof x == 'string'); // [['a', '3'],[2, 3]]
partition([1, 2, 3, 4], x => typeof x == 'number'); // [[1, 2, 3, 4],[]]
partition([1, 2, 3, 4], x => typeof x == 'string'); // [[], [1, 2, 3, 4]]
partition([], n => n > 3); // [[], []]
partition({a: 1, b: 2}, n => n > 1); // throws
partition(null, n => n > 1); // throws
partition(undefined, n => n > 1); // throws

source

🍦 Try it

npm install just-permutations
yarn add just-permutations

Returns all permutations of the length N of the elements of the given Array

import permutations from 'just-permutations';

permutations([1, 2, 3]); // [[1, 2, 3], [2, 1, 3], [2, 3, 1], [1, 3, 2], [3, 1, 2], [3, 2, 1]]
permutations([]); // []
permutations(); // throws

source

🍦 Try it

npm install just-range
yarn add just-range

Generate a range array for numbers

import range from 'just-range';

range(1, 5); // [1, 2, 3, 4]
range(5); // [0, 1, 2, 3, 4]
range(-5); // [0, -1, -2, -3, -4]
range(0, 20, 5) // [0, 5, 10, 15]

source

🍦 Try it

npm install just-remove
yarn add just-remove

Removes one array from another

import remove from 'just-remove';

remove([1, 2, 3, 4, 5, 6], [1, 3, 6]); // [2, 4, 5]

source

🍦 Try it

npm install just-union
yarn add just-union

Returns the union of two arrays

import union from 'just-union';

union([1, 2, 5, 6], [2, 3, 4, 6]); // [1, 2, 5, 6, 3, 4]

source

🍦 Try it

npm install just-zip-it
yarn add just-zip-it

Returns an array of grouped elements, taking n-th element from every given array

import zip from 'just-zip-it';

zip([1, 2, 3]); // [[1], [2], [3]]
zip([1, 2, 3], ['a', 'b', 'c']); // [[1, 'a'], [2, 'b'], [3, 'c']]
zip([1, 2], ['a', 'b'], [true, false]); //[[1, 'a', true], [2, 'b', false]]

zip(undefined, {}, false, 1, 'foo'); // []
zip([1, 2], ['a', 'b'], undefined, {}, false, 1, 'foo'); // [[1, 'a'], [2, 'b']]

zip([1, 2, 3], ['a', 'b'], [true]); // [[1, 'a', true], [2, 'b', undefined], [3, undefined, undefined]]

source

🍦 Try it

npm install just-group-by
yarn add just-group-by

Return a grouped object from array

import groupBy from 'just-group-by';

groupBy([6.1, 4.2, 6.3], Math.floor); // { '4': [4.2], '6': [6.1, 6.3] }
groupBy([1,2,3,4,5,6,7,8], function(i) { return i % 2}); // { '0': [2, 4, 6, 8], '1': [1, 3, 5, 7] }

Statistics

source

🍦 Try it

npm install just-mean
yarn add just-mean

The mean (average) value in an array

import mean from 'just-mean';

mean([1, 2, 3, 2, 4, 1]); // 2.1666666667
mean(3, 2, 1); // 2
mean([4]); // 4
mean(['3', 2]); // throws
mean(); // throws

source

🍦 Try it

npm install just-median
yarn add just-median

Return the median value of an array of numbers

import median from 'just-median';

median([1, 2, 3, 4, 5]); // 3
median([3, -1, 2]); // 2
median([9, 14, 14, 200, 15]); // 14
median(1, 2, 4, 3); // 2.5
median(['3', 2, 1]); // throws
median(); // throws

source

🍦 Try it

npm install just-mode
yarn add just-mode

Return the most frequently occuring number(s)

import mode from 'just-mode';

mode([1, 2, 3, 2]); // 2
mode(4, 4, 1, 4); // 4
mode(100, 100, 101, 101); // [100, 101]
mode(4, 3, 2, 1); // [1, 2, 3, 4]
mode(['1', 2, 2, 1, 2]); // throws
mode(null); // throws

source

🍦 Try it

npm install just-percentile
yarn add just-percentile

Return the value at the given percentile (using linear interpolation)

import percentile from 'just-percentile';

percentile([1, 2, 3], 0); // 1
percentile([1, 2, 3], 0.5); // 2
percentile([1, 2, 3], 1); // 3

// See https://en.wikipedia.org/wiki/Percentile (linear interpolation method)
percentile([15, 20, 35, 40, 50], 0.05); // 15
percentile([15, 20, 35, 40, 50], 0.3); // 20
percentile([15, 20, 35, 40, 50], 0.4); // 27.5
percentile([15, 20, 35, 40, 50], 0.95); // 50

percentile(1, 2, 3, 50); // throws
percentile(['1', 2, 3], 50); // throws
percentile([], 50); // throws

source

🍦 Try it

npm install just-variance
yarn add just-variance

Return the standard deviation of an array or numeric argument list

import variance from 'just-variance';

variance([1, 2, 3, 2, 4, 1]); // 1.3666666667
variance(3, 2, 1); // 1
variance([100, 100, 100.1, 100]); // 0.0025
variance(1, 2, 3, 4, 5, -6); // 15.5
variance([4]); // throws
variance(['3', 2]); // throws
variance(NaN, NaN); // throws
variance(); // throws

source

🍦 Try it

npm install just-standard-deviation
yarn add just-standard-deviation

Return the standard deviation of an array or numeric argument list

import standardDeviation from "just-standard-deviation";

standardDeviation([1, 2, 3, 2, 4, 1]); // 1.16904519
standardDeviation(3, 2, 1); // 1
standardDeviation([100, 100, 100.1, 100]); // 0.05
standardDeviation(1, 2, 3, 4, 5, -6); // 3.9370039
standardDeviation([4]); // throws
standardDeviation(["3", 2]); // throws
standardDeviation(NaN, NaN); // throws
standardDeviation(); // throws

source

🍦 Try it

npm install just-skewness
yarn add just-skewness

Return the skewness of an array or numeric argument list using Pearson's second skewness coefficient

import skewness from "just-skewness";

// Using Pearson's second skewness coefficient
skewness(3, 2, 1); // 0
skewness([1, 2, 3, 2, 4, 1]); // 0.4276994613841504
skewness(1, 2, 3, 4, 5, -6); // -0.762000762001143
skewness([1, 2, 3, 4, 9]); // 0.7705935588815224
skewness([4]); // throws
skewness(["3", 2]); // throws
skewness(NaN, NaN); // throws
skewness(); // throws

Strings

source

🍦 Try it

npm install just-template
yarn add just-template

Interpolate a string with variables

import template from 'just-template';

var data = {
  a: {
    aa: {
      aaa: 'apple',
      bbb: 'pear'
    },
    bb: 'orange'
  },
  b: 'plum'
};
template('2 {{a.aa.aaa}}s, a {{a.aa.bbb}}, 3 {{a.bb}}s and a {{b}}. Yes 1 {{a.aa.bbb}}.', data);
// '2 apples, a pear, 3 oranges and a plum. Yes 1 pear.'

source

🍦 Try it

npm install just-truncate
yarn add just-truncate

Truncate a string with a custom suffix

  truncate('when shall we three meet again', 9); // 'when s...'
  truncate('when shall we three meet again', 10, ' (etc)'); // 'when (etc)'
  truncate('when shall we', 15,); // 'when shall we'
  truncate('when shall we', 15, '(more)'); // 'when shall we'
  truncate('when shall we', 10, ' (etc etc etc)'); // ' (etc etc etc)'

source

🍦 Try it

npm install just-prune
yarn add just-prune

Prune a string with whole words and a custom suffix

  prune('when shall we three meet again', 7); // 'when...'
  prune('when shall we three meet again', 7, ' (more)'; // 'when (more)'
  prune('when shall we', 15,); // 'when shall we'
  prune('when shall we', 15, ' (etc)'); // 'when shall we'
  prune('when shall we', 7, ' (more)'); // ' (more)'

source

🍦 Try it

npm install just-squash
yarn add just-squash

Remove all spaces from a string, optionally remove escape sequences too

  squash('the cat sat on the mat'); // 'thecatsatonthemat'
  squash(' the cat sat on the mat '); // 'thecatsatonthemat'
  squash('\tthe cat\n sat \fon \vthe \rmat '); // '\tthecat\nsat\fon\vthe\rmat'
  squash('\tthe cat\n sat \fon \vthe \rmat ', true); // 'thecatsatonthemat'
  squash(`the cat
sat on the mat`, true); // thecatsatonthemat

source

🍦 Try it

npm install just-left-pad
yarn add just-left-pad

Add characters to the left of a string such that its total length is n

import leftPad from 'just-left-pad';

leftPad('hello', 9); // '    hello'
leftPad('hello', 3); // 'hello'
leftPad('hello', 9, '.'); // '....hello'
leftPad('hello', 9, '..'); // '....hello'
leftPad('hello', 10, 'ab'); // 'bababhello'
leftPad('hello', 9, '\uD83D\uDC04'); // 'πŸ„πŸ„πŸ„πŸ„hello'
leftPad('hello', 10, '\uD83D\uDC11\uD83D\uDC04'), // 'πŸ„πŸ‘πŸ„πŸ‘πŸ„hello'
leftPad('hello', 7, 'πŸ„'), // 'πŸ„πŸ„hello'
leftPad(null, 7); // throws
leftPad([], 4, '*'); // throws
leftPad('hello', 4, true); // throws
leftPad('hello', -4, true); // throws  
leftPad('hello', 2.3, true); // throws    

source

🍦 Try it

npm install just-right-pad
yarn add just-right-pad

Add characters to the right of a string such that its total length is n

import rightPad from 'just-right-pad';

rightPad('hello', 9); // 'hello    '
rightPad('hello', 3); // 'hello'
rightPad('hello', 9, '.'); // 'hello....'
rightPad('hello', 9, '..'); // 'hello....'
rightPad('hello', 10, 'ab'); // 'helloababa'
rightPad('hello', 9, '\uD83D\uDC04'); // 'helloπŸ„πŸ„πŸ„πŸ„'
rightPad('hello', 10, '\uD83D\uDC11\uD83D\uDC04'), // 'helloπŸ‘πŸ„πŸ‘πŸ„πŸ‘'
rightPad('hello', 7, 'πŸ„'), // 'helloπŸ„πŸ„'
rightPad(null, 7); // throws
rightPad([], 4, '*'); // throws
rightPad('hello', 4, true); // throws
rightPad('hello', -4, true); // throws  
rightPad('hello', 2.3, true); // throws    

source

🍦 Try it

npm install just-camel-case
yarn add just-camel-case

Convert a string to camel case

  import camelCase from 'just-camel-case';

  camelCase('the quick brown fox'); // 'theQuickBrownFox'
  camelCase('the_quick_brown_fox'); // 'theQuickBrownFox'
  camelCase('the-quick-brown-fox'); // 'theQuickBrownFox'
  camelCase('theQuickBrownFox'); // 'theQuickBrownFox'
  camelCase('thequickbrownfox'); // 'thequickbrownfox'
  camelCase('the - quick * brown# fox'); // 'theQuickBrownFox'
  camelCase('behold theQuickBrownFox'); // 'beholdTheQuickBrownFox'
  camelCase('Behold theQuickBrownFox'); // 'beholdTheQuickBrownFox'
  // all caps words are camel-cased
  camelCase('The quick brown FOX'), 'theQuickBrownFox');
  // all caps substrings >= 4 chars are camel-cased
  camelCase('theQUickBrownFox'); // 'theQUickBrownFox'
  camelCase('theQUIckBrownFox'); // 'theQUIckBrownFox'
  camelCase('theQUICKBrownFox'); // 'theQuickBrownFox'

source

🍦 Try it

npm install just-kebab-case
yarn add just-kebab-case

Convert a string to kebab case

  import kebabCase from 'just-kebab-case';

  kebabCase('the quick brown fox'); // 'the-quick-brown-fox'
  kebabCase('the-quick-brown-fox'); // 'the-quick-brown-fox'
  kebabCase('the_quick_brown_fox'); // 'the-quick-brown-fox'
  kebabCase('theQuickBrownFox'); // 'the-quick-brown-fox'
  kebabCase('theQuickBrown Fox'); // 'the-quick-brown-fox'
  kebabCase('thequickbrownfox'); // 'thequickbrownfox'
  kebabCase('the - quick * brown# fox'); // 'the-quick-brown-fox'
  kebabCase('theQUICKBrownFox'); // 'the-q-u-i-c-k-brown-fox'

source

🍦 Try it

npm install just-snake-case
yarn add just-snake-case

Convert a string to snake case

  import snakeCase from 'just-snake-case';

  snakeCase('the quick brown fox'); // 'the_quick_brown_fox'
  snakeCase('the-quick-brown-fox'); // 'the_quick_brown_fox'
  snakeCase('the_quick_brown_fox'); // 'the_quick_brown_fox'
  snakeCase('theQuickBrownFox'); // 'the_quick_brown_fox'
  snakeCase('thequickbrownfox'); // 'thequickbrownfox'
  snakeCase('the - quick * brown# fox'); // 'the_quick_brown_fox'
  snakeCase('theQUICKBrownFox'); // 'the_q_u_i_c_k_brown_fox'

source

🍦 Try it

npm install just-pascal-case
yarn add just-pascal-case

Convert a string to pascal case

  import pascalCase from 'just-pascal-case';

  pascalCase('the quick brown fox'); // 'TheQuickBrownFox'
  pascalCase('the_quick_brown_fox'); // 'TheQuickBrownFox'
  pascalCase('the-quick-brown-fox'); // 'TheQuickBrownFox'
  pascalCase('theQuickBrownFox'); // 'TheQuickBrownFox'
  pascalCase('thequickbrownfox'); // 'Thequickbrownfox'
  pascalCase('the - quick * brown# fox'); // 'TheQuickBrownFox'
  pascalCase('theQUICKBrownFox'); // 'TheQUICKBrownFox'

source

🍦 Try it

npm install just-capitalize
yarn add just-capitalize

Capitalize the first character of a string

  import capitalize from 'just-capitalize';

/*
  capitalize('capitals'); // 'Capitals'
  capitalize('Capitals'); // 'Capitals'
  capitalize('many words'); // 'Many words'
  capitalize('!exclaim'); // '!exclaim'
*/

source

🍦 Try it

npm install just-replace-all
yarn add just-replace-all

Replace all occurrences of a string within a string with another string

  import replaceAll from 'just-replace-all';

/*
  replaceAll('hello, world', 'l', 'q'); // 'heqqo, worqd'
  replaceAll('hello, world', 'l', 'qq'); // 'heqqqqo, worqqd'
  replaceAll('hello, world', 'll', 'q'); // 'heqo, world'
  replaceAll('hello, world', '', 'q'); // 'hello, world'
  replaceAll('hello, world', 'l', ''); // 'heo, word'
  replaceAll('hello, world', null, 'q'); // 'hello, world'
  replaceAll('hello, world', 'l'); // throw
  replaceAll('hello, world'); // throw
  replaceAll(); // throw
  replaceAll(null, 'l', 'q'); // throw
  replaceAll('hello, world', null, 'q'); // throw
  replaceAll('hello, world', 'l', null); // throw
*/

Numbers

source

🍦 Try it

npm install just-clamp
yarn add just-clamp

Restrict a number within a range

import clamp from 'just-clamp';

var n = 5;
clamp(1, n, 12); // 5
clamp(3, n, 1); // 3
clamp(8, n, 9); // 8
clamp(0, n, 0); // 0

var n = -5;
clamp(1, n, 12); // 1
clamp(-7, n, -8); // -7

clamp(NaN, n, 8); // NaN
clamp(3, n, NaN); // NaN  
clamp(3, NaN, 8); // NaN    

clamp(undefined, n, 8); // throws
clamp(3, n, 'h'); // throws  
clamp(3, false, 8); // throws 

source

🍦 Try it

npm install just-is-prime
yarn add just-is-prime

Check if number is prime

  import isPrime from 'just-is-prime;

/*
  isPrime(1); // false
  isPrime(2); // true
  isPrime(17); // true
  isPrime(10); // false
  isPrime(); // throws
  isPrime(null); // throws
  isPrime("js"); // throws
  isPrime({}); // throws
  isPrime(function() {}); // throws
  isPrime([]); // throws
*/

source

🍦 Try it

npm install just-modulo
yarn add just-modulo

Modulo of a number and a divisor

import modulo from 'just-modulo';

modulo(7, 5); // 2
modulo(17, 23); // 17
modulo(16.2, 3.8); // 1
modulo(5.8, 3.4); //2.4
modulo(4, 0); // 4
modulo(-7, 5); // 3
modulo(-2, 15); // 13
modulo(-5.8, 3.4); // 1
modulo(12, -1); // NaN
modulo(-3, -8); // NaN
modulo(12, 'apple'); // NaN
modulo('bee', 9); // NaN
modulo(null, undefined); // NaN

source

🍦 Try it

npm install just-random-integer
yarn add just-random-integer

Produces a random integer within a given range

import random from 'just-random-integer';

random();
// Returns either 0 or 1
random(5);
// Returns a random integer between 0 and 5 (inclusively)
random(3, 10);
// Returns a random integer between 3 and 10 (inclusively)
random(-5.8, 10.4);
// Returns a random integer between -5 and 10 (inclusively)

Functions

source

🍦 Try it

npm install just-compose
yarn add just-compose

Return a function composed of 2 or more functions

import compose from 'just-compose';

const sqRootBiggest = compose(Math.max, Math.sqrt, Math.trunc);
sqRootBiggest(10, 5); // 3
sqRootBiggest(7, 0, 16); // 4

source

🍦 Try it

npm install just-curry-it
yarn add just-curry-it

Return a curried function

import curry from 'just-curry-it';

function add(a, b, c) {
  return a + b + c;
}
curry(add)(1)(2)(3); // 6
curry(add)(1)(2)(2); // 5
curry(add)(2)(4, 3); // 9

function add(...args) {
  return args.reduce((sum, n) => sum + n, 0)
}
var curryAdd4 = curry(add, 4)
curryAdd4(1)(2, 3)(4); // 10

function converter(ratio, input) {
  return (input*ratio).toFixed(1);
}
const curriedConverter = curry(converter)
const milesToKm = curriedConverter(1.62);
milesToKm(35); // 56.7
milesToKm(10); // 16.2

source

🍦 Try it

npm install just-demethodize
yarn add just-demethodize

Turn a method into a standalone function; the first arg becomes this

import demethodize from 'just-demethodize';

const trimFn = demethodize(''.trim);
['hello ', ' goodbye', 'hello again'].map(trimFn); // ['hello', 'goodbye', 'hello again']

source

🍦 Try it

npm install just-flip
yarn add just-flip

Flip first two arguments of a function

import flip from 'just-flip';

flip(console.log)(1, 2, 3) // 2, 1, 3

import map from 'just-map-object';
import partial from 'just-partial';

const numbers = {x: 5, y: 10};
const flippedMap = flip(map);
const double = partial(flippedMap, (undefined, number) => number * 2);
double(numbers) // {x: 10, y: 20];

source

🍦 Try it

npm install just-partial-it
yarn add just-partial-it

Return a partial function

import partial from 'just-partial-it';

const cubedRoot = partial(Math.pow, _, 1/3);
cubedRoot(64); // 4

const getRoot = partial(Math.pow, 64);
getRoot(1/2); // 8

source

🍦 Try it

npm install just-pipe
yarn add just-pipe

Pass a value through a pipeline of functions

import pipe from 'just-pipe

pipe(3, a => a+1, b => b*2) // 8
pipe('John Smith', a => a.split(' '), b => b.reverse(), c => c[0]) // 'Smith'

source

🍦 Try it

npm install just-debounce-it
yarn add just-debounce-it

Return a debounced function

import debounce from "just-debounce-it";

const fn1 = debounce(() => console.log("Hello"), 500);
fn1();
fn1();
fn1();
// 500ms later logs 'hello' once

const fn2 = debounce(() => console.log("Hello"), 500, true);
fn2(); // logs hello immediately
fn2();
fn2();
// 500ms later logs 'hello' once

const fn3 = debounce(() => console.log("Hello"), 500);
fn3();
fn3();
fn3();
fn3.cancel();
// function cancelled before 'hello' is logged

const fn4 = debounce(() => console.log("Hello"), 500);
fn4();
fn4();
fn4();
fn4.flush();
// immediately invoke the debounced function

source

🍦 Try it

npm install just-memoize
yarn add just-memoize

An implementation of the memoize technique

import memoize from 'just-memoize';

const sumByOne = memoize(function(value) {
  return value + 1;
});

sumByOne(10); // Returns value returned by the function
sumByOne(10); // Cache hit!

sumByOne(20); // Returns value returned by the function
sumByOne(20); // Cache hit!

// Custom cache key (key defaults to JSON stringified arguments)
var sum = memoize(function(a, b) {
  return a + b;
}, function(a, b) {
  return `${a}-${b}`;
});

sum(10, 10); // Returns value returned by the function
sum(10, 20); // Returns value returned by the function
sum(10, 20); // Cache hit!

source

🍦 Try it

npm install just-memoize-last
yarn add just-memoize-last

A memoize implementation that only caches the most recent evaluation

const memoizeLast = require('just-memoize-last')
const compare = require('just-compare')

const maxValue = memoizeLast(function(arr) {
  return Math.max(...arr)
}, function(a, b) {
  return compare(a, b)
});

maxValue([1,2,3]) // 3
maxValue([1,2,3]) // cache hit!
maxValue([1,3,4]) // 4
maxValue([1,2,3]) // 3

source

🍦 Try it

npm install just-random
yarn add just-random

Return a randomly selected element in an array

import random from 'just-random';

random([1, 2, 3]);
// one of [1, 2, 3], at random

source

🍦 Try it

npm install just-throttle
yarn add just-throttle

Return a throttled function

import throttle from 'just-throttle';

// no matter how many times the function is called, only invoke once within the given interval
// options: 
// `leading`: invoke  before interval
// `trailing`: invoke afer interval

const fn1 = throttle(() => console.log('hello'), 500, {leading: true});
setInterval(fn1, 400);
// logs 'hello' immediately and then every 500ms

const fn2 = throttle(() => console.log('hello'), 500, {trailing: true});
setInterval(fn2, 400);
// logs 'hello' after 500ms and then every 500ms

const fn3 = throttle(() => console.log('hello'), 500, {leading: true, trailing: true});
// forces trailing to false

const fn4 = throttle(() => console.log('hello'), 500, { leading: false });
fn4();
fn4();
fn4();
fn4.cancel();
// function cancelled before 'hello' is logged

const fn5 = throttle(() => console.log("Hello"), 500);
fn5();
fn5();
fn5();
fn5.flush();
// immediately invoke the throttled function

source

🍦 Try it

npm install just-once
yarn add just-once

Create a function that can only be invoked once

import once from 'just-once';

const fn = once(() => console.log('hello'));

fn();
// logs 'hello'
fn();
// does nothing

Testing

Run all tests as a single test suite with

npm run test

Cross browser tests (via saucelabs) are in the sauce branch

Contribute!

https://github.com/angus-c/just/blob/master/CONTRIBUTING.md

just's People

Contributors

alexmsmithca avatar angus-c avatar aryaman1706 avatar brandonryan avatar cameronhunter avatar chee avatar chocolateboy avatar craigbeck avatar dawsbot avatar dimfeld avatar djtb avatar dylanpiercey avatar ecto avatar evandrolg avatar ewlin avatar jakub-g avatar jonathan-fielding avatar justyrobles avatar kamilogorek avatar kathawala avatar linkiwi avatar masa-shin avatar maxsynnott avatar pe8ter avatar puruvj avatar renovate[bot] avatar saibotsivad avatar scdf avatar seiyab avatar tclark1011 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

just's Issues

just-camel-case not a drop-in replacement for lodash.camelcase

There are some cases where just-camel-case produces subtly different results from lodash.camelcase. I noticed this while trying to replace lodash.camelcase with this library (redux-utilities/redux-actions#331).

I made a quick comparison: https://repl.it/@heygrady/camelcase

Sadly, just-camel-case returns different results when the initial string is in all caps. I tried adding the strict option but then it failed when the initial string was already in camelcase.

  1. It feels like strict mode should be the default (but that's not such a big deal)
  2. Strict mode needs to check if the input string is already in camelcase

The to-camel-case lib handles this by detecting if a word is in camelCase and splits it. From there the join logic you already have would work.

Here (https://repl.it/@heygrady/just-camel-case) is a naiive combination of the logic from to-camel-case with what just-camel-case does:

const wordSeparators = /[\s\u2000-\u206F\u2E00-\u2E7F\\'!"#$%&()*+,\-.\/:;<=>?@\[\]^_`{|}~]+/;
const hasCamel = /([a-z][A-Z]|[A-Z][a-z])/;
const camelSplitter = /(.)([A-Z]+)/g;

function uncamelize(str) {
  return str.replace(camelSplitter, function (m, previous, uppers) {
    return previous + ' ' + uppers.toLowerCase().split('').join(' ');
  }).split(' ');
}

function camelCase(str, options) {
  var words = str.split(wordSeparators);
  var len = words.length;
  var strict = options && options.strict;
  var mappedWords = new Array(len);
  for (var i = 0; i < words.length; i++) {
    var word = words[i];
    if (word === '') {
      continue;
    }
    if (strict && hasCamel.test(word)) {
      var camelWords = uncamelize(str);
      Array.prototype.splice.apply(words, [i, 1].concat(camelWords));
      word = words[i];
    }
    var firstLetter = word[0];
    firstLetter =
      i > 0 ?
        firstLetter.toUpperCase() :
        strict ? firstLetter.toLowerCase() : firstLetter;
    mappedWords[i] = firstLetter + (strict ? word.slice(1).toLowerCase() : word.slice(1));
  }
  return mappedWords.join('');
}

LICENSE file missing in npm package

Hello, is it possible to incorporate the LICENSE file inside the npm package ? Now it's missing. It's implied by MIT license that if licensed under the MIT the source code must be accompanied by full license text. If the license file is not in the npm package a lot of people cannot use it (technically, nobody can).

Thank you

just-partial-it implementation questions

Hey,

I got curious about the implementations you've got here - mostly for my own learning purposes. When I was playing with just-partial-it I had trouble understanding what role theglobalObj has?

var globalObj = global || self;
globalObj.___ = {};

And taking that down through the code, what does this line do?

derivedArgs[i] = thisPartialArg === globalObj.___ ? arguments[argIndex++] : thisPartialArg;

It looks like it checks to see if thisPartialArg === {} which would always evaluate to false.

Like I said, I just want to learn. =D

just-pick without undefined values

Currently just-pick returns undefined values for not found keys. I'm not sure where this can be useful. For me it's basically always a problem.

In lodash it's done differently, it never returns undefined values.

Maybe it makes sense to add a 3rd parameter that will allow to skip undefined values? Or maybe add a breaking change (new version) that will remove undefined values by default? That would be the best

startsWith/endsWith

Those ES6 method could be implemented in relative elegant way with performance in mind.

For endsWith we could use:

function endsWith(string, searchString, endPos) {
    var len = string.length,
        searchLen = searchString.length,
        startPos;

    if (endPos === undefined) {
        endPos = len;
        startPos = len - searchLen;
    }
    else {
        endPos = Math.min(Math.max(+endPos || 0, 0), len);
        startPos = endPos - searchLen;
    }

    return startPos >= 0 && string.slice(startPos, endPos) === searchString;
}

Please note polyfill here https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith and Lodash use indexOf which is harmful with long strings and specified endPos argument.

just-diff fails on array or object with null member value

const {diff, jsonPatchPathConverter} = require('just-diff')

diff(
{a: 'a', b:null, c:'b'},
{a: 'a', b:'b'},
/* jsonPatchPathConverter */
);

result in:
Array (2 items)
0: Object
op: "remove"
path: ["c"]
1: Object
op: "add"
path: ["b"]
value: "b"

should it be:
Array (2 items)
0: Object
op: "remove"
path: ["c"]
1: Object
op: "replace"
path: ["b"]
value: "b"

just-merge/just-extend any object.

Looks like the last release changed just-extend to have an object type check.

I personally use the utility for functions like so:

function MyPerfectLib () {}
const statics = { ... }

extend(MyPerfectLib, statics)

It'd be nice if this could be supported again.


Edit: Also this a breaking change and published as a patch release.

Output of just-diff not compatible with just-diff-apply for arrays

When the output of just-diff on an array is run through just-diff-apply, the resulting array is not the same:

> let a = [1, 2, 3, 4, 5]
[ 1, 2, 3, 4, 5 ]
> let b = [5]
[ 5 ]
> let c = diff(a, b)
[ { op: 'remove', path: [ 1 ] },
  { op: 'remove', path: [ 2 ] },
  { op: 'remove', path: [ 3 ] },
  { op: 'remove', path: [ 4 ] },
  { op: 'replace', path: [ 0 ], value: 5 } ]
> diffApply(a, c)
Error: expected to find property 3 in object 1,3,5
    at diffApply (/.../node_modules/just-diff-apply/index.js:90:15)

Is this behaviour expected?

Bundling

Hey. Newbie here. would it be possible to include a way of bundling only packages I need together instead of npm installing them on a one by one basis. If this goes against what you're trying to do i'd appreciate if you could explain. thanks.

default export diff and diffApply

First of all: Thank you for the collection, this is just what I needed!

There's a slight inconsistency on the module exports. All other utils have a default export except for diff and diffApply. It should be trivial fix this without breaking existing use of the libraries.

import diff from 'just-diff'

could and should be supported alongside with

import { diff } from 'just-diff'

Let me know what you think. I can create a PR if you agree.

just-range crashes devtools

Hi @angus-c!
Awesome collection, I use it here and there.
One gotcha:

let range = require('just-range');
range(5.4, 11.200000000000001, 0.2)

Crashes devtools.

Typings needed

Would you be giving typings for these modules any time soon ?

Allow undefined in just-extend

Going in the lines with Object.assign(), undefined should be allowed as an argument.

Actual Behavior

const x = extend({}, {a:'x'}, undefined) //throws error

Expected Behaviour

const x = extend({}, {a:'x'}, undefined) //{a: "x"}  

lodash

const x = _.assignIn({}, {a: 'x'},Β undefined) //{a: "x"}

Object.assign

const x = Object.assign({}, {a: 'x'},Β undefined) //{a: "x"}

Most of the times, I will be using it as a polyfill for Object.assign so I really will want just-extend to have an API similar to it?

Commited node modules

Hi

I noticed that the node_modules folder is committed to the project, can we add this to the git ignore file and remove it?

Thanks

Jonathan

Reconsider TypeScript

TypeScript type definitions were already requested in #20 and #66 back in 2016-2017, but the landscape has changed much since then.

Two concerns were expressed in #20, that you would like to avoid, which I will address below, but first let me state the value proposition.

Value Proposition

For a library such as this, it makes all the sense in the world for the source to be written in TypeScript for the following reasons:

  1. The type definition files (*.d.ts) can be generated at compile time for free. Nobody has to manually update these files, leading to version out-of-sync issues.
  2. Types remain in sync with each version that is published. You just can't get this feature without TS source code.
  3. You don't have to install two packages for each "just" package (e.g., npm install --save just-omit && npm install --save-dev @types/just-omit).
  4. Users who don't use TypeScript can still benefit via Automatic Type Acquisition.

Transpilation step

There's obviously no getting around this one if TS were to be used, but I'd like to know, specifically, what the concerns around the transpilation step are.

Size increase

This one is probably a misconception, an outdated fear or an exaggeration. As a superset of JavaScript, TypeScript seeks not to add any language constructs of their own. As long as we steer away from inheritance and down-level compilation, there's really nothing to fear here. All the type information and interfaces disappear at compile time.

Let's take just-omit as an example. Currently, if I remove the comments, the file size is 193 bytes min / 177 bytes min + gzip.

If I were to convert it into TypeScript, it would look something like this:

export = omit

/**
 * The opposite of `just-pick`; this method creates an object composed of the
 * own and inherited enumerable properties of `object` that are not omitted.
 * 
 * @category Object
 * @returns A new object with specified keys omitted from the source `object`.
 * @example ...
 */
function omit<T extends object, K extends keyof T>(
  /**
   * The source object.
   */
  object: T | null | undefined,
  /**
   * The property names to omit.
   */
  ...paths: Array<K | ReadonlyArray<K>>
) {
  const result = {} as Pick<T, Exclude<keyof T, K>>;
  for (const prop in object) {
    if (!object.hasOwnProperty || object.hasOwnProperty(prop)) {
      if (paths.indexOf(prop as unknown as K) === -1) {
        result[prop as string] = object[prop];
      }
    }
  }
  return result
}

Which compiles to 214 bytes min / 190 bytes min + gzip:

"use strict";
function omit(object) {
    var paths = [];
    for (var _i = 1; _i < arguments.length; _i++) {
        paths[_i - 1] = arguments[_i];
    }
    var result = {};
    for (var prop in object) {
        if (!object.hasOwnProperty || object.hasOwnProperty(prop)) {
            if (paths.indexOf(prop) === -1) {
                result[prop] = object[prop];
            }
        }
    }
    return result;
}
module.exports = omit;

The delta is only 21 bytes and 13 bytes, respectively, and I could have avoided that if I stuck to the current just-omit implementation and didn't use the spread (...) operator for paths.

Point is, it's basically the same, but you gain so much value in serving the community with the type information they need. Even if they aren't using TypeScript, editors like vscode can still pull-in type information via type acquisition, so everybody wins.

Automatic Type Acquisition works for dependencies downloaded by npm (specified in package.json), Bower (specified in bower.json), and for many of the most common libraries listed in your folder structure (for example jquery-3.1.1.min.js).

Conclusion

As long as you're open to the idea, I think the community can start to submit PRs incrementally. There's no reason everything has to be done all at once.

diff path emptied

I'm using both just-diff and just-diff-apply and I noticed that once an array of diffs (I called it dif) is passed into diffApply, the path field of the objects in that array are empty which I didn't expect and I'm not sure I should have expected that.

Example code:

const { diff } = require('just-diff')
const { diffApply } = require('just-diff-apply')

let old = [['Hello', 'world']]
let cur = [['Hello', 'all']]

let dif = diff(old, cur) //[{ op: 'replace', path: ['0', '1'], value: 'all' }]
let copy = [...old]
let fixed = diffApply(copy, dif) // ['Hello', 'all']
copy; // [['Hello', 'all']]
dif; //[{ op: 'replace', path: [], value: 'all' }]

Numeric object property

Good day!
What about case, when Integer used as Object property, for example:

{
  c: 1,
  b: 2,
  a: 3,
  13: ['d1', 'd2', {i: 'ok'}]
  ^ problem is here
}

In diff path it looks like Array index...
It would be useful if the pathConverter method would have a second argument with types...

Capitalize replacement

I notice there is a lack of a capitalize package, similar to capitalize provided by lodash.

I'm using the pascal-case module for now, but it removes dashes where I don't want it to.

Would you be up for adding a capitalize package if I open a PR?

Switch to typescript.

@angus-c not sure if you are a fan of typescript but I think it's worth considering converting 'just' packages to use it.

Primarily this would be great for users as it would bring autocompletion for VSCode (or atom with plugin) with inline docs. You can also achieve this by creating 'typings' files however there are many other advantages to using typescript.

If you are interested in this I'd be willing to lend a hand setting up the scripts and converting the modules (I've recently started doing this with some of my own modules).

Just thought I'd gauge your interest in this idea.

just-flip example code broken/doesn't work as expected?

I was looking at just-flip,

I thought the example code looked interesting so I copied it into runkit, however the code does not git the expected result, an in the comments
It actually fails with an error,

I tried to fix the example, but I couldn't quite work it out
something about the combination of just-flip and just-map-object

const flip = require('just-flip');
const map = require('just-map-object');
const curry = require('just-curry');

const numbers = {x: 5, y: 10};
const flippedMap = flip(map);
const double = curry(flippedMap, (_, number) => number * 2);
double(numbers) // {x: 10, y: 20];

https://runkit.com/vidhill/59e13d4ae9c3a00012eb22a8

Conflicts with es6 template string

The syntax of template is exactly the same as the es6 one. As a result, if there is file contain template string and read by just-template, it will modify before the parsing of es6 parsing.

I suggest the change the identifier like {{i.am.a.template}} won't conflict with the es6 one.

latest release broke require('sinon')

mkdir newproj && cd newproj
npm init -y
npm i -S [email protected]
node -e 'require("sinon")'

Ouptut:

~/newproj/node_modules/just-extend/index.js:40
      throw new Error('expected object, got ' + arg);
      ^

Error: expected object, got function FakeXMLHttpRequest(config) {
    EventTargetHandler.call(this);
    this.readyState = FakeXMLHttpRequest.UNSENT;
    this.requestHeaders = {};
    this.requestBody = null;
    this.status = 0;
    this.statusText = "";
    this.upload = new EventTargetHandler();
    this.responseType = "";
    this.response = "";
    this.logError = configureLogError(config);

    if (sinonXhr.supportsTimeout) {
        this.timeout = 0;
    }

    if (sinonXhr.supportsCORS) {
        this.withCredentials = false;
    }

    if (typeof FakeXMLHttpRequest.onCreate === "function") {
        FakeXMLHttpRequest.onCreate(this);
    }
}
    at extend (~/newproj/node_modules/just-extend/index.js:40:13)
    at Object.<anonymous> (~/newproj/node_modules/nise/lib/fake-xhr/index.js:651:1)
    at Module._compile (module.js:570:32)
    at Object.Module._extensions..js (module.js:579:10)
    at Module.load (module.js:487:32)
    at tryModuleLoad (module.js:446:12)
    at Function.Module._load (module.js:438:3)
    at Module.require (module.js:497:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (~newproj/node_modules/nise/lib/fake-server/index.js:3:15)

$ npm ls just-extend
[email protected] ~/newproj
└─┬ [email protected]
  └─┬ [email protected]
    └── [email protected] 

$ node --version
v6.11.0

Re: sinonjs/sinon#1591

Just vs lodash

Lodash doesn't have dependencies and its methods can be imported individually, e.g.

extend = require('lodash/extend')
// vs 
extend = require('just-extend')

How do just modules compare to equivalent lodash methods?

just-once

For functions that should only be invoked once:

/**
 * Call a function at most one time.
 *
 * @param {function} fn - the function to wrap.
 * @return {function}
 */
function once (fn) {
  return function wrap () {
    if (wrap) return wrap.value
    wrap.called = true
    return wrap.value = fn()
  }
}

Usage:

const initialize = once(() => { ... })

initialize() // Called.
initialize() // Not invoked.

Switch to namespaced modules.

Great list of modules here. I think it would be a good idea to switch to scoped modules with a public org.

There are several benefits here:

  1. There is no chance that someone could steal a package name.
  2. Users can more trust just packages without worrying about squaters/malware.
  3. You can more easily give other developers access/control of individual repo's and manage it all from one org.

The only problem is that just is taken. Luckily it's a squated package with no docs and hasn't been updated for 5 years. You should have no issue retrieving this if you email NPM, but it can take some time.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.