A collection of modern native JavaScript object and array utilities

on in Featured, JavaScript Arrays & Objects, Methods, Events and Scopes
Last modified on

Table of Contents

Arrays

Chunk

Creates an array of elements split into groups the length of size.

const chunk = (input, size) => {
  return input.reduce((arr, item, idx) => {
    return idx % size === 0
      ? [...arr, [item]]
      : [...arr.slice(0, -1), [...arr.slice(-1)[0], item]];
  }, []);
};

chunk(['a', 'b', 'c', 'd'], 2);
// => [['a', 'b'], ['c', 'd']]

chunk(['a', 'b', 'c', 'd'], 3);
// => [['a', 'b', 'c'], ['d']]

Compact

Creates an array with all falsy values removed.

[0, 1, false, 2, '', 3].filter(Boolean)
// output: [1, 2, 3]

Concatenate

Creates a new array concatenating additional arrays and/or values.

var array = [1]
var other = array.concat(2, [3], [[4]])

console.log(other)
// output: [1, 2, 3, [4]]

Difference

Similar to without, but returns the values from the array that are not present in the other arrays.

var arrays = [[1, 2, 3, 4, 5], [5, 2, 10]];
console.log(arrays.reduce(function(a, b) {
  return a.filter(function(value) {
    return !b.includes(value);
  });
}));
// output: [1, 3, 4]

let arrays = [[1, 2, 3, 4, 5], [5, 2, 10]];
console.log(arrays.reduce((a, b) => a.filter(c => !b.includes(c))));
// output: [1, 3, 4]

Drop

Creates a slice of an array with n elements dropped from the beginning.

[1, 2, 3].slice(1);
// => [2, 3]

[1, 2, 3].slice(2);
// => [3]

Drop Right

Creates a slice of an array with n elements dropped at the end.

[1, 2, 3].slice(0, -1);
// => [1, 2]

[1, 2, 3].slice(0, -2);
// => [1]

Fill

Fills elements of an array with a value from start up to, but not including, end.

var array = [1, 2, 3]

array.fill('a')

console.log(array)
// output: ['a', 'a', 'a']

Array(3).fill(2)
// output: [2, 2, 2]

[4, 6, 8, 10].fill('*', 1, 3)
// output: [4, '*', '*', 10]

Find

Returns the value of the first element in the array that satisfies a condition. Otherwise, undefined is returned.

let users = [
  { 'user': 'barney',  'age': 36, 'active': true },
  { 'user': 'fred',    'age': 40, 'active': false },
  { 'user': 'pebbles', 'age': 1,  'active': true }
]

users.find(function (o) { return o.age < 40; })
// output: object for 'barney'

Find Index

Returns the index of the first element in the array that satisfies a condition. Otherwise, -1 is returned.

let users = [
  { 'user': 'barney',  'age': 36, 'active': true },
  { 'user': 'fred',    'age': 40, 'active': false },
  { 'user': 'pebbles', 'age': 1,  'active': true }
]

var index = users.findIndex(function (o) { return o.age >= 40; })
console.log(index)
// output: 1

First

Returns the first element of an array. Passing n will return the first n elements of the array.

[1, 2, 3, 4, 5][0];
// => 1
//or
[].concat(1, 2, 3, 4, 5).shift()
// => 1
//or
[].concat([1, 2, 3, 4, 5]).shift()
// => 1

// Works even with potentially undefined/null
[].concat(undefined).shift()
// => undefined

[1, 2, 3, 4, 5].slice(0, 2);
// => [1, 2]

Flatten

Flattens an array a single level deep.

const flatten = [1, [2, [3, [4]], 5]].reduce( (a, b) => a.concat(b), [])
// => [1, 2, [3, [4]], 5]

const flatten = [].concat(...[1, [2, [3, [4]], 5]])
// => [1, 2, [3, [4]], 5]

// ES2019
const flatten = [1, [2, [3, [4]], 5]].flat()
// => [1, 2, [3, [4]], 5]

const flatten = [1, [2, [3, [4]], 5]].flatMap(number => number)
// => [1, 2, [3, [4]], 5]

Flatten Deep

Recursively flattens an array.

const flattenDeep = (arr) => Array.isArray(arr)
  ? arr.reduce( (a, b) => a.concat(flattenDeep(b)) , [])
  : [arr]

flattenDeep([1, [[2], [3, [4]], 5]])
// => [1, 2, 3, 4, 5]

// ES2019
[1, [2, [3, [4]], 5]].flat(Infinity)
// => [1, 2, 3, 4, 5]

const flattenDeep = (arr) => arr.flatMap((subArray, index) => Array.isArray(subArray) ? flattenDeep(subArray) : subArray)

flattenDeep([1, [[2], [3, [4]], 5]])
// => [1, 2, 3, 4, 5]

From Pairs

Returns an object composed of key/value pairs.

const fromPairs = function(arr) {
  return arr.reduce(function(accumulator, value) {
    accumulator[value[0]] = value[1];
    return accumulator;
  }, {})
}

// Compact form
const fromPairs = (arr) => arr.reduce((acc, val) => (acc[val[0]] = val[1], acc), {})

fromPairs([['a', 1], ['b', 2]]);
// => { 'a': 1, 'b': 2 }

// ES2019
Object.fromEntries([['a', 1], ['b', 2]])
// => { 'a': 1, 'b': 2 }

Head and Tail

Gets the first element or all but the first element.

const array = [1, 2, 3]

const [ head, ...tail ] = array
console.log(head)
// output: 1
console.log(tail)
// output [2, 3]

indexOf

Returns the first index at which a given element can be found in the array, or -1 if it is not present.

var array = [2, 9, 9]
var result = array.indexOf(2)
console.log(result)
// output: 0

Intersection

Returns an array that is the intersection of all the arrays. Each value in the result is present in each of the arrays.

var arrays = [[1, 2, 3], [101, 2, 1, 10], [2, 1]];
console.log(arrays.reduce(function(a, b) {
  return a.filter(function(value) {
    return b.includes(value);
  });
}));
// output: [1, 2]

let arrays = [[1, 2, 3], [101, 2, 1, 10], [2, 1]];
console.log(arrays.reduce((a, b) => a.filter(c => b.includes(c))));
// output: [1, 2]

Take Right

Creates a slice of array with n elements taken from the end.

[1, 2, 3].slice(-1);
// => [3]

[1, 2, 3].slice(-2);
// => [2, 3]

[1, 2, 3].slice(-5);
// => [1, 2, 3]

isArray

Returns true if given value is an array.

var array = []
console.log(Array.isArray(array));
// output: true

isArrayBuffer

Checks if a value is classified as an ArrayBuffer object.

console.log(new ArrayBuffer(2) instanceof ArrayBuffer);
// output: true

Join

Joins a list of elements in an array with a given separator.

var result = ['one', 'two', 'three'].join('--')
console.log(result)
// output: 'one--two--three'

Last

Returns the last element of an array. Passing n will return the last n elements of the array.

const numbers = [1, 2, 3, 4, 5];
numbers[numbers.length - 1];
// => 5
//or
numbers.slice(-1)[0];
// => 5
//or
[].concat(numbers).pop()
// => 5
//or
numbers.at(-1);
// => 5

// Works even with potentially undefined/null
[].concat(undefined).pop()
// => undefined

numbers.slice(-2);
// => [4, 5]

lastIndexOf

Returns the index of the last occurrence of the value in the array, or -1 if the value is not present.

var array = [2, 9, 9, 4, 3, 6]
var result = array.lastIndexOf(9)
console.log(result)
// output: 2

Reverse

Reverses an array so that the first element becomes the last, the second element becomes the second to last, and so on.

var array = [1, 2, 3]
console.log(array.reverse())
// output: [3, 2, 1]

Slice

Returns a shallow copy of a portion of an array into a new array object selected from begin to end (end not included).

var array = [1, 2, 3, 4]
console.log(array.slice(1, 3));
// output: [2, 3]

Without

Returns an array where matching items are filtered.

var array = [1, 2, 3]
console.log(array.filter(function(value) {
  return value !== 2;
}));
// output: [1, 3]

Initial

Returns everything but the last entry of the array. Pass n to exclude the last n elements from the result.

var array = [5, 4, 3, 2, 1]
console.log(array.slice(0, -2));
// output: [5, 4, 3]

Pull

Removes all provided values from the given array using strict equality for comparisons (i.e. ===).

const array = [1, 2, 3, 1, 2, 3];
function pull(arr, ...removeList){
    var removeSet = new Set(removeList)
    return arr.filter(function(el){
        return !removeSet.has(el)
    })
}
console.log(pull(array, 2, 3)); // output: [1, 1]
console.log(array); // still [1, 2, 3, 1, 2, 3]

unionBy

Creates an array of unique values, taking an iteratee to compute uniqueness with (note that to iterate by a key in an object you must use x => x.key, instead of key for the iteratee).

In functional programming, an iteratee is a composable abstraction for incrementally processing sequentially presented chunks of input data in a purely functional fashion.

var array1 = [2.1];
var array2 = [1.2, 2.3];
function unionBy(...arrays) {
    const iteratee = (arrays).pop();

    if (Array.isArray(iteratee)) {
        return []; // return empty if iteratee is missing
    }

    return [...arrays].flat().filter(
        (set => (o) => set.has(iteratee(o)) ? false : set.add(iteratee(o)))(new Set()),
    );
};
console.log(unionBy(array1, array2, Math.floor))
// output: [2.1, 1.2]

Collections

Each

Iterates over a list of elements, yielding each in turn to an iteratee function.

// For arrays
[1, 2, 3].forEach(function (value, index) {
  console.log(value)
})
// output: 1 2 3

// For objects
Object.entries({'one':1, 'two':2, 'three':3}).forEach(function([key,value],index) {
  console.log(value)
})
//output: 1 2 3

Every

Tests whether all elements in the array pass the test implemented by the condition.

function isLargerThanTen (element, index, array) {
  return element >= 10
}

var array = [10, 20, 30]
var result = array.every(isLargerThanTen)
console.log(result)
// output: true

Filter

Creates a new array with all elements that pass the test implemented by the condition.

function isBigEnough (value) {
  return value >= 10
}
var array = [12, 5, 8, 130, 44]
var filtered = array.filter(isBigEnough)
console.log(filtered)
// output: [12, 130, 44]

Group By

Group items by key.

var grouped = ['one', 'two', 'three'].reduce((r, v, i, a, k = v.length) => ((r[k] || (r[k] = [])).push(v), r), {})
console.log(grouped)
// output: {3: ["one", "two"], 5: ["three"]}

var grouped = [1.3, 2.1, 2.4].reduce((r, v, i, a, k = Math.floor(v)) => ((r[k] || (r[k] = [])).push(v), r), {})
console.log(grouped)
// output: {1: [1.3], 2: [2.1, 2.4]}

Includes

Checks if a value is in collection.

var array = [1, 2, 3]
array.includes(1)
// output: true

// Does not use same value zero
var array = [1, 2, 3]
array.indexOf(1) > -1
// output: true

keyBy

Creates an object composed of keys generated from the results of running each element of collection through an iteratee.

console.log(keyBy(['a', 'b', 'c']))
// output: { a: 'a', b: 'b', c: 'c' }
console.log(keyBy([{ id: 'a1', title: 'abc' }, { id: 'b2', title: 'def' }], 'id'))
// output: { a1: { id: 'a1', title: 'abc' }, b2: { id: 'b2', title: 'def' } }
console.log(keyBy(Object.values({ data: { id: 'a1', title: 'abc' }}), 'id'))
// output: { a1: { id: 'a1', title: 'abc' }}

// keyBy for array and object
const collectionKeyBy = (collection, key) => {
  const c = collection || {};
  return c.isArray() ? keyBy(c, key) : keyBy(Object.values(c), key);
}

Map

Translates all items in an array or object to new array of items.

var array1 = [1, 2, 3]
var array2 = array1.map(function (value, index) {
  return value * 2
})
console.log(array2)
// output: [2, 4, 6]

var object1 = { 'a': 1, 'b': 2, 'c': 3 }
var object2 = Object.entries(object1).map(function ([key, value], index) {
  return value * 2
})
console.log(object2)
// output: [2, 4, 6]

Minimum By and Maximum By

Use Array.reduce to find the maximum or minimum collection item.

In functional programming, a functor is a design pattern inspired by the definition from category theory that allows one to apply a function to values inside a generic type without changing the structure of the generic type.

var data = [{ value: 6 }, { value: 2 }, { value: 4 }]
var minItem = data.reduce(function(a, b) { return a.value <= b.value ? a : b }, {})
var maxItem = data.reduce(function(a, b) { return a.value >= b.value ? a : b }, {})
console.log(minItem, maxItem)
// output: { value: 2 }, { value: 6 }

// Extract a functor and use es2015 for better code
// utils
const makeSelect = (comparator) => (a, b) => comparator(a, b) ? a : b
const minByValue = makeSelect((a, b) => a.value <= b.value)
const maxByValue = makeSelect((a, b) => a.value >= b.value)

// main logic
const data = [{ value: 6 }, { value: 2 }, { value: 4 }]
const minItem = data.reduce(minByValue, {})
const maxItem = data.reduce(maxByValue, {})

console.log(minItem, maxItem)
// output: { value: 2 }, { value: 6 }

// or also more universal and little slower variant of minBy
const minBy = (collection, key) => {
  // slower because need to create a lambda function for each call...
  const select = (a, b) => a[key] <= b[key] ? a : b
  return collection.reduce(select, {})
}

console.log(minBy(data, 'value'))
// output: { value: 2 }

Pluck

A shorthand which plucks and maps an array with an iteratee.

var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = array1.map(function(x){
  return x.name
})
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]

Reduce

Applies a function against an accumulator and each value of the array (from left-to-right) to reduce it to a single value.

var array = [0, 1, 2, 3, 4]
var result = array.reduce(function (previousValue, currentValue, currentIndex, array) {
  return previousValue + currentValue
})
console.log(result)
// output: 10

Range

Creates an array of numbers progressing from start up to a given value.

// Using Array.from
Array.from({length: 4}, (_, i) => i)  // output: [0, 1, 2, 3]
Array.from({length: 4}, (_, i) => -i) // output: [-0, -1, -2, -3]
Array.from({length: 4}, (_, i) => i + 1) // output: [1, 2, 3, 4]
Array.from({length: 4}, (_, i) => i * 5) // output: [0, 5, 10, 15]

// Using keys() and spread
[...Array(4).keys()]  // output: [0, 1, 2, 3]
[...Array(4).keys()].map(k => -k) // output: [-0, -1, -2, -3]
[...Array(4).keys()].map(k => k + 1)  // output: [1, 2, 3, 4]
[...Array(4).keys()].map(k => k * 5)  // output: [0, 5, 10, 15]

Reduce Right

This method iterates over elements of the collection from right to left.

var array = [0, 1, 2, 3, 4]
var result = array.reduceRight(function (previousValue, currentValue, currentIndex, array) {
  return previousValue - currentValue
})
console.log(result)
// output: -2

Reject

This method returns the elements of a collection that predicate does not return truthy for.

var array = [1, 2, 3, 4, 5];

var reject = function (arr, predicate) {
  var complement = function (f) {
    return function (x) {
      return !f(x);
    }
  };

  return arr.filter(complement(predicate));
};
// output: [1, 3, 5]

Sample

Gets a random element from an array.

const array = [0, 1, 2, 3, 4]
const sample = arr => {
  const len = arr == null ? 0 : arr.length
  return len ? arr[Math.floor(Math.random() * len)] : undefined
}

const result = sample(array)
console.log(result)
// output: 2

Size

Returns the number of values in the collection.

var result2 = Object.keys({one: 1, two: 2, three: 3}).length
console.log(result2)
// output: 3

Some

Tests whether any of the elements in the array pass the test implemented by the condition.

function isLargerThanTen (element, index, array) {
  return element >= 10
}

var array = [10, 9, 8]
var result = array.some(isLargerThanTen)
console.log(result)
// output: true

Sort By and Order By

Sorts an array of objects based on an object key provided by a parameter.

const fruits = [
  {name:"banana", amount: 2},
  {name:"apple", amount: 4},
  {name:"pineapple", amount: 2},
  {name:"mango", amount: 1}
];

const sortBy = (key) => {
  return (a, b) => (a[key] > b[key]) ? 1 : ((b[key] > a[key]) ? -1 : 0);
};

// sort() modifies the array in place. We use `.concat()` to copy the array, then sort
fruits.concat().sort(sortBy("name"));
// => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}]

Unique

Produces a duplicate-free version of the array, using === to test object equality.

var array = [1, 2, 1, 4, 1, 3];
var result = [...new Set(array)];
console.log(result)
// output: [1, 2, 4, 3]

Functions

After

Creates a version of the function that will only be run after first being called count times. Useful for grouping asynchronous responses, where you want to be sure that all the async calls have finished, before proceeding.

var notes = ['profile', 'settings']

notes.forEach(function (note, index) {
  console.log(note)
  if (notes.length === (index + 1)) {
    render()
  }
})

Bind

This code defines two objects, objA and objB, and creates a bound function boundOffsetX using the bind method.

objA is an object with two properties: x and offsetX. The x property is assigned a value of 66. The offsetX property is a function that takes an offset parameter and returns the sum of this.x (the x property of the object calling the function) and the offset value.

objB is another object with a single property x assigned a value of 67.

The bind method is then used to create a new function boundOffsetX that is bound to objB. The bind method creates a new function that, when called, has its this value set to the object provided as the first argument (objB in this case). The second argument (0 in this case) is a parameter that is partially applied to the original function (objA.offsetX). This means that whenever boundOffsetX is called, it will always have objB as the this value and 0 as the offset parameter.

So, boundOffsetX is a function that, when called, will always return the sum of objB.x (67) and 0, which is 67.

var objA = {
  x: 66,
  offsetX: function(offset) {
    return this.x + offset;
  }
}

var objB = {
  x: 67
};

var boundOffsetX = objA.offsetX.bind(objB, 0);

isFunction

Checks if a value is classified as a Function object.

function isFunction(func) {
  return typeof func === "function";
}

isFunction(setTimeout);
// => true

isFunction(123);
// => false

Debounce

The given code defines a debounce function that takes three parameters: func (the function to be debounced), wait (the delay in milliseconds), and immediate (a boolean flag indicating whether the function should be invoked immediately).

The debounce function returns a new function that wraps the original function provided as func. This new function will delay the execution of func until a certain amount of time (wait) has passed since the last invocation.

Within the returned function, a timeout variable is declared to store the timeout identifier. On each invocation of the returned function, the timeout is cleared using clearTimeout(timeout). This ensures that any previous timeouts are canceled.

Then, a new timeout is set using setTimeout. This timeout function has an inner function that checks if immediate is false (indicating that the debounced function should not be called immediately) and if the timeout is null. If both conditions are true, the original func is called with the provided context (this) and arguments (args) using the apply method.

After setting the timeout, another check is performed to see if immediate is true and if the timeout is null. If both conditions are true, the original func is immediately called with the provided context and arguments.

The last line of code attaches an event listener to the window’s resize event. It calls the debounce function, passing calculateLayout as the function to be debounced and 150 as the delay. This ensures that the calculateLayout function is executed only after 150 milliseconds of the last resize event, effectively debouncing the function call.

function debounce(func, wait, immediate) {
  let timeout;
  return function() {
    const context = this;
    const args = arguments;
    clearTimeout(timeout);
    timeout = setTimeout(() => {
      timeout = null;
      if (!immediate) func.apply(context, args);
    }, wait);
    if (immediate && !timeout) func.apply(context, args);
  };
}

window.addEventListener('resize', debounce(calculateLayout, 150));

Partial

This code creates a partial function application.

The greet function takes two parameters, greeting and name, and concatenates them to form a greeting string.

In the ES5 version, the sayHelloTo variable is declared as an arrow function. It uses the rest parameter syntax (...args) to collect any number of arguments passed to sayHelloTo. The arrow function then invokes the greet function, passing the string 'Hello' as the first argument (fixed) and spreading the collected arguments (...args) as the second argument (name). The result is assigned to the result variable, and it logs 'Hello Jose' to the console.

In the ES6 version, the partial function is defined using arrow function syntax. It takes a func parameter (the target function to be partially applied) and boundArgs (the arguments to be bound or pre-set). The partial function returns another arrow function that takes remainingArgs as its parameters. This inner arrow function then invokes func by spreading the boundArgs and remainingArgs using the spread syntax (...boundArgs, ...remainingArgs). The resulting function is assigned to the sayHelloTo variable by partially applying the greet function with the string 'Hello'. The result is assigned to the result variable and logged to the console, resulting in the output 'Hello Jose'.

In summary, both versions of the code demonstrate how to create a partial function application using JavaScript. The partial function allows you to pass some arguments to a function in advance and generate a new function that only requires the remaining arguments to be passed later. This technique can be useful when you want to reuse a function with certain fixed arguments in different contexts.

// ES5
function greet(greeting, name) {
  return greeting + ' ' + name;
}
var sayHelloTo = (...args) => greet('Hello', ...args)
var result = sayHelloTo('Jose')
console.log(result)
// output: 'Hello Jose'

// ES6
const partial = (func, ...boundArgs) => (...remainingArgs) => func(...boundArgs, ...remainingArgs)
var sayHelloTo = partial(greet, 'Hello');
var result = sayHelloTo('Jose')
console.log(result)
// output: 'Hello Jose'

Throttle

The throttle function takes two parameters: func (the function to be throttled) and timeFrame (the time interval in milliseconds). It returns a new function that wraps the original func and limits its execution to once within the specified timeFrame.

Inside the returned function, a lastTime variable is declared and initialized to 0. This variable stores the timestamp of the last time the throttled function was called.

On each invocation of the returned function, a new now variable is created, representing the current timestamp using new Date(). The difference between now and lastTime is calculated, and if it exceeds or equals the specified timeFrame, the throttled func is called with the provided arguments using the spread syntax (...args), and lastTime is updated to the current timestamp.

The purpose of the throttle function is to prevent the calculateLayout function from being executed multiple times within the specified time interval (150 milliseconds in this case). It ensures that the calculateLayout function is called at most once within that timeframe, even if the resize event is triggered multiple times.

The last line of code attaches an event listener to the window’s resize event, using addEventListener. It calls the throttle function, passing calculateLayout as the function to be throttled and 150 as the time interval. This ensures that the calculateLayout function is throttled and executed at most once every 150 milliseconds when the resize event occurs.

function throttle(func, timeFrame) {
  let lastTime = 0;
  return function(...args) {
    const now = new Date();
    if (now - lastTime >= timeFrame) {
      func(...args);
      lastTime = now;
    }
  };
}

window.addEventListener('resize', throttle(calculateLayout, 150));

Cast Array

Puts the value into an array of length one if it is not already an array.

function castArray(arr) {
  return Array.isArray(arr) ? arr : [arr]
}
// output: true
console.log(castArray(5));
// output: [5]
console.log(castArray([2]));
// output: [2]

Is Date

Checks if a value is classified as a Date object.

console.log(Object.prototype.toString.call(new Date) === "[object Date]");
// output: true

Greater Than

Checks if a value is greater than another.

console.log(3 > 1);
// output: true

Greater Than or Equal

Checks if a value is greater than or equal to another.

console.log(3 >= 1);
// output: true

Is Empty

Checks if a value is an empty object or collection.

const isEmpty = obj => [Object, Array].includes((obj || {}).constructor) && !Object.entries((obj || {})).length;

console.log(isEmpty(null))
// output: true
console.log(isEmpty(''))
// output: true
console.log(isEmpty({}))
// output: true
console.log(isEmpty([]))
// output: true
console.log(isEmpty({a: '1'}))
// output: false

Is Finite

Checks if a value is a finite primitive number.

console.log(Number.isFinite('3'))
// output: false
console.log(Number.isFinite(3))
// output: true

Is Integer

Checks if a value is an integer.

console.log(Number.isInteger(3))
// output: true
console.log(Number.isInteger('3'))
// output: false

Is Not a Number (NaN)

Checks if a value is NaN.

// ES5
console.log(isNaN(NaN))
// output: true

// ES6
console.log(Number.isNaN(NaN))
// output: true

In comparison to the global isNaN() function, Number.isNaN() doesn’t suffer the problem of forcefully converting the parameter to a number. This means it is now safe to pass values that would normally convert to NaN, but aren’t actually the same value as NaN. This also means that only values of the type number, that are also NaN, return true. Number.isNaN()

MDN

Is Nil

Checks if a value is null or undefined.

console.log(null == null);
// output: true
console.log(NaN == null);
// output: false
console.log(undefined == null)
// output: true

Is Null

Checks if a value is null.

console.log(null === null);
// output: true
console.log(void 0 === null);
// output: false

Is Undefined

Checks if a value is undefined.

console.log(typeof a === 'undefined');
// output: true
console.log(a === undefined);
// output: true

Assign

This method is used to copy the values of all enumerable own properties from one or more source objects to a target object.

function Foo() {
  this.c = 3;
}
function Bar() {
  this.e = 5;
}
Foo.prototype.d = 4;
Bar.prototype.f = 6;
var result = Object.assign({}, new Foo, new Bar);
console.log(result);
// output: { 'c': 3, 'e': 5 }

Defaults

This method is used to apply new values over an object with default values for keys.

const newValues = {a: 3};
const defaultValues = {a: 1, b: 2}
const appliedValues = Object.assign({}, defaultValues, newValues);
// output { a: 3, b: 2 }

Extend

This method is used to copy the values of all enumerable own and inherited properties from one or more source objects to a target object.

function Foo() {
  this.c = 3;
}
function Bar() {
  this.e = 5;
}
Foo.prototype.d = 4;
Bar.prototype.f = 6;
var result = Object.assign({}, new Foo, Foo.prototype, new Bar, Bar.prototype);
console.log(result);
// output: { 'c': 3, 'd': 4, 'e': 5, 'f': 6 }

//Or using a function
const extend = (target, ...sources) => {
 const length = sources.length;

  if (length < 1 || target == null) return target;
  for (let i = 0; i < length; i++) {
    const source = sources[i];

    for (const key in source) {
      target[key] = source[key];
    }
  }
  return target;
};
console.log(extend({}, new Foo, new Bar));
// output: { 'c': 3, 'd': 4, 'e': 5, 'f': 6 }

Has

Checks if key is a direct property of object. key may be a path of a value separated by .

const has = function (obj, key) {
  var keyParts = key.split('.');

  return !!obj && (
    keyParts.length > 1
      ? has(obj[key.split('.')[0]], keyParts.slice(1).join('.'))
      : hasOwnProperty.call(obj, key)
  );
};

var object = { a: 1, b: 'settings' };
var result = has(object, 'a');
// output: true

_.get

Get

Gets the value at path of object. If the provided path does not exist inside the object, it will generate an error.

// ES6
var object = { a: [{ b: { c: 3 } }] };
var { a: [{ b: { c: result = 1 } = {} } = {}] = [] } = object;
console.log(result);
// output: 3

// ES11
var object = { a: [{ b: { c: 3 } }] };
var result = object?.a?.[0]?.b?.c ?? 1;
console.log(result);
// output: 3

// ES5
const get = (obj, path, defaultValue = undefined) => {
  const travel = regexp =>
    String.prototype.split
      .call(path, regexp)
      .filter(Boolean)
      .reduce((res, key) => (res !== null && res !== undefined ? res[key] : res), obj);
  const result = travel(/[,[\]]+?/) || travel(/[,[\].]+?/);
  return result === undefined || result === obj ? defaultValue : result;
};

var object = { a: [{ b: { c: 3 } }] };
var result = get(object, 'a[0].b.c', 1);
// output: 3

Keys

Retrieves all the names of the object’s own enumerable properties.

var result2 = Object.keys({one: 1, two: 2, three: 3})
console.log(result2)
// output: ["one", "two", "three"]

Omit

Returns a copy of the object, filtered to omit the keys specified.

var object = { 'a': 1, 'b': '2', 'c': 3 };

var { a, c, ...result2 } = object;
console.log(result2)
// output: { 'b': '2' }

Pick

Creates an object composed of the object properties the predicate returns truthy for.

var object = { 'a': 1, 'b': '2', 'c': 3 };

const { a, c } = object;
const result = { a, c};
console.log(result);
// output: {a: 1, c: 3}
// for an array of this object --> array.map(({a, c}) => ({a, c}));

function pick(object, keys) {
  return keys.reduce((obj, key) => {
     if (object && object.hasOwnProperty(key)) {
        obj[key] = object[key];
     }
     return obj;
   }, {});
}
var result = pick(object, ['a', 'c']);
console.log(result)
// output: {a: 1, c: 3}

Pick By

Creates an object composed of the object properties the predicate returns truthy for.

var object = { 'a': 1, 'b': null, 'c': 3, 'd': false, 'e': undefined };

function pickBy(object) {
    const obj = {};
    for (const key in object) {
        if (object[key]) {
            obj[key] = object[key];
        }
    }
    return obj;
}
var result = pickBy(object);
console.log(result)
// output: {a: 1, c: 3}

To Pairs

Retrieves all the given object’s own enumerable property [ key, value ] pairs.

var result2 = Object.entries({one: 1, two: 2, three: 3})
console.log(result2)
// output: [["one", 1], ["two", 2], ["three", 3]]

Values

Retrieves all the given object’s own enumerable property values.

var result2 = Object.values({one: 1, two: 2, three: 3})
console.log(result2)
// output: [1, 2, 3]

Strings

Capitalize

Converts the first character of a string to upper case and the remaining to lower case.

const capitalize = (string) => {
  return string ? string.charAt(0).toUpperCase() + string.slice(1).toLowerCase() : '';
};

var result = capitalize('FRED');
console.log(result);
// => 'Fred'

Ends With

Checks if a string ends with the given target string.

'abc'.endsWith('c');
// => true

'abc'.endsWith('b');
// => false

'abc'.endsWith('b', 2);
// => true

Is String

Checks if a value is classified as a String primitive or object.

function isString(str){
  if (str != null && typeof str.valueOf() === "string") {
    return true
  }
  return false
}

isString('abc');
// => true

isString(123);
// => false

Lower First

Converts the first character of a string to lower case.

const lowerFirst = (string) => {
  return string ? string.charAt(0).toLowerCase() + string.slice(1) : ''
}

var result = lowerFirst('Fred')
console.log(result)
// output: 'fred'

_.padStart and _.padEnd

Pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length.

console.log('123'.padStart(5, '0'))
// output: '00123'

console.log('123'.padEnd(5, '0'))
// output: '12300'

_.repeat

Repeats the given string n times.

var result = 'abc'.repeat(2)
console.log(result)
// output: 'abcabc'

_.replace

Returns a new string with some or all matches of a pattern replaced by a replacement

var re = /apples/gi;
var str = 'Apples are round, and apples are juicy.';
var result = str.replace(re, 'oranges');
console.log(result);
// output: 'oranges are round, and oranges are juicy.'

_.split

Splits string by separator.

var result = 'a-b-c'.split('-', 2)
console.log(result)
// output: ['a','b']

_.startsWith

Checks if string starts with the given target string.

var result = 'abc'.startsWith('b', 1)
console.log(result)
// output: true

_.template

Create a template function.

const templateLiteral = (value) => `hello ${value.user}`;
var result = templateLiteral({ 'user': 'fred' });
console.log(result);
// output: 'hello fred'

_.toLower

Lowercases a given string.

var result = 'FOOBAR'.toLowerCase()
console.log(result)
// output: 'foobar'

_.toUpper

Uppercases a given string.

var result = 'foobar'.toUpperCase()
console.log(result)
// output: 'FOOBAR'

_.trim

Removes the leading and trailing whitespace characters from a string.

var result = ' abc '.trim()
console.log(result)
// output: 'abc'

_.upperFirst

Uppercases the first letter of a given string

const upperFirst = (string) => {
  return string ? string.charAt(0).toUpperCase() + string.slice(1) : ''
}

var result = upperFirst('george')
console.log(result)
// output: 'George'

_.uniqWith

similar to _.uniq except that it accepts comparator which is invoked to compare elements of array. The order of result values is determined by the order they occur in the array.

const uniqWith = (arr, fn) => arr.filter((element, index) => arr.findIndex((step) => fn(element, step)) === index);

const array = [1, 2, 2, 3, 4, 5, 2];
const result = uniqWith(array, (a, b) => a === b);
console.log(result);
// output: [1, 2, 3, 4, 5]

const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
const result = uniqWith(objects, (a, b) => JSON.stringify(a) === JSON.stringify(b));
console.log(result);
// output: [{ x: 1, y: 2 }, { x: 2, y: 1 }]

Util

_.times

Invokes the iteratee n times, returning an array of the results of each invocation.

var result = Array.from({length: 10}, (_,x) => x)
console.log(result)
// output: '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'

var result = [...Array(10).keys()]
console.log(result)
// output: '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]'

Number

_.clamp

Clamps number within the inclusive lower and upper bounds.

const clamp = (number, boundOne, boundTwo) => {
  if (!boundTwo) {
    return Math.max(number, boundOne) === boundOne ? number : boundOne;
  } else if (Math.min(number, boundOne) === number) {
    return boundOne;
  } else if (Math.max(number, boundTwo) === number) {
    return boundTwo;
  }
  return number;
};

clamp(-10, -5, 5);
// => -5

clamp(10, -5, 5);
// => 5

clamp(10, -5);
// => -5

clamp(10, 99);
// => 10

_.inRange

Checks if n is between start and up to, but not including, end. If end is not specified, it’s set to start with start then set to 0. If start is greater than end, the parameters are swapped to support negative ranges.

  const inRange = (num, init, final) => {
    if(final === undefined){
      final = init;
      init = 0;
    }
    return (num >= Math.min(init, final) && num < Math.max(init, final));
  }

  const inRange = (num, a, b=0) => (Math.min(a,b) <= num && num < Math.max(a,b));

  inRange(3, 2, 4);
  // output: true
  inRange(-3, -2, -6);
  // output: true

_.random

Produces a random number between the inclusive lower and upper bounds. If only one argument is provided, a number between 0 and the given number is returned. If floating is true, or either lower or upper are floats, a floating-point number is returned instead of an integer.

const random = (a = 1, b = 0) => {
    const lower = Math.min(a, b);
    const upper = Math.max(a, b);
    return lower + Math.random() * (upper - lower);
};

const randomInt = (a = 1, b = 0) => {
    const lower = Math.ceil(Math.min(a, b));
    const upper = Math.floor(Math.max(a, b));
    return Math.floor(lower + Math.random() * (upper - lower + 1))
  };

  random();
  // => a floating-point number between 0 and 1

  random(5);
  // => a floating-point number between 0 and 5

  random(0, 5);
  // => also a floating-point number between 0 and 5

  random(1.2, 5.2);
  // => a floating-point number between 1.2 and 5.2

  randomInt();
  // => just 0 or 1

  randomInt(5);
  // => an integer between 0 and 5

  randomInt(0, 5);
  // => also an integer between 0 and 5

  randomInt(1.2, 5.2);
  // => an integer between 2 and 5

Related posts