Lawrence  Lesch

Lawrence Lesch

1659664140

List Of JavaScript Methods Which You Can Use Natively + ESLint Plugin

You don't (may not) need Lodash/Underscore

Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.

You are welcome to contribute with more items provided below.

If you are targeting legacy JavaScript engine with those ES5 methods, you can use es5-shim

Please note that, the examples used below are just showing you the native alternative of performing certain tasks. For some functions, Lodash provides you more options than native built-ins. This list is not a 1:1 comparison.

Please send a PR if you want to add or modify the code. No need to open an issue unless it's something big and you want to discuss.

Voice of Developers

Make use of native JavaScript object and array utilities before going big.

—Cody Lindley, Author of jQuery Cookbook and JavaScript Enlightenment

You probably don't need Lodash. Nice List of JavaScript methods which you can use natively.

—Daniel Lamb, Computer Scientist, Technical Reviewer of Secrets of the JavaScript Ninja and Functional Programming in JavaScript

I guess not, but I want it.

—Tero Parviainen, Author of build-your-own-angular

I'll admit, I've been guilty of overusing #lodash. Excellent resource.

—@therebelrobot, Maker of web things, Facilitator for Node.js/io.js

ESLint Plugin    

If you're using ESLint, you can install a plugin that will help you identify places in your codebase where you don't (may not) need Lodash/Underscore.

Install the plugin...

npm install --save-dev eslint-plugin-you-dont-need-lodash-underscore

...then update your config

"extends" : ["plugin:you-dont-need-lodash-underscore/compatible"],

For more information, see Configuring the ESLint Plugin

Important: Note that, while many Lodash methods are null safe (e.g. _.keys, _.entries), this is not necessarily the case for their Native equivalent. If null safety is critical for your application, we suggest that you take extra precautions [e.g. consider using the native Object.keys as Object.keys(value || {})].

Collection*

Important: Note that most native equivalents are array methods, and will not work with objects. If this functionality is needed and no object method is provided, then Lodash/Underscore might be the better option. Bear in mind however, that all iterable objects can easily be converted to an array by use of the spread operator.

Array

_.chunk

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

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

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


// Native

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']]

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.compact

Creates an array with all falsy values removed.

// Underscore/Lodash
_.compact([0, 1, false, 2, '', 3]);

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

Browser Support for array.prototype.filter

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.concat

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

// Underscore/Lodash
var array = [1]
var other = _.concat(array, 2, [3], [[4]])

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

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

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

Browser Support for Array.prototype.concat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.difference

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

// Underscore/Lodash
console.log(_.difference([1, 2, 3, 4, 5], [5, 2, 10]))
// output: [1, 3, 4]

// Native
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]

// ES6
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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.drop

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

// Underscore/Lodash
_.drop([1, 2, 3]);
// => [2, 3]

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.dropRight

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

// Underscore/Lodash
_.dropRight([1, 2, 3]);
// => [1, 2]

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.fill

Fills elements of array with value from start up to, but not including, end. Note that fill is a mutable method in both native and Lodash/Underscore.

// Underscore/Lodash
var array = [1, 2, 3]

_.fill(array, 'a')

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

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

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

// Native
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]

Browser Support for Array.prototype.fill()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔31.0 ✔32.0 ✔8 ✔

⬆ back to top

_.find

Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

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

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

// Native
var 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'

Browser Support for Array.prototype.find()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔25.0 ✔32.0 ✔7.1 ✔

⬆ back to top

_.findIndex

Returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.

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

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

// Native
var 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

Browser Support for Array.prototype.findIndex()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔25.0 ✔32.0 ✔7.1 ✔

⬆ back to top

_.first

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

// Underscore/Lodash
_.first([1, 2, 3, 4, 5]);
// => 1

// Underscore
_.first([1, 2, 3, 4, 5], 2);
// => [1, 2]

// Native
[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

// Native (works even with potentially undefined/null, like _.first)
[].concat(undefined).shift()
// => undefined

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.flatten

Flattens array a single level deep.

// Underscore/Lodash
_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]

// Native
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]

// Native(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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔3.0 ✔9.0 ✔10.5 ✔4 ✔

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.prototype.flatMap()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

⬆ back to top

_.flattenDeep

Recursively flattens array.

// Underscore/Lodash
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]

// Native
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]

// Native(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]

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔16.0 ✔37.0 ✔7.1 ✔

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.prototype.flatMap()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

⬆ back to top

_.fromPairs

Returns an object composed from key-value pairs.

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

// Native
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 }

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

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

Browser Support for Object.fromEntries()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
73.0 ✔79.0 ✔63.0 ✔60 ✔12.1 ✔

⬆ back to top

_.head and _.tail

Gets the first element or all but the first element.

const array = [1, 2, 3]

// Underscore: _.first, _.head, _.take
// Lodash: _.first, _.head
_.head(array)
// output: 1

// Underscore: _.rest, _.tail, _.drop
// Lodash: _.tail
_.tail(array)
// output: [2, 3]


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

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.indexOf

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

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

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

Browser Support for Array.prototype.indexOf()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.intersection

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

// Underscore/Lodash
console.log(_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]))
// output: [1, 2]

// Native
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]

// ES6
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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.takeRight

Creates a slice of array with n elements taken from the end. :heavy_exclamation_mark: Native slice does not behave entirely the same as the Lodash method. See example below to understand why.

// Underscore/Lodash
_.takeRight([1, 2, 3]);
// => [3]

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

_.takeRight([1, 2, 3], 5);
// => [1, 2, 3]

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

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

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

// Difference in compatibility

// Lodash
_.takeRight([1, 2, 3], 0);
// => []

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.isArray

Returns true if given value is an array.

// Lodash
var array = []
console.log(_.isArray(array))
// output: true

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

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

⬆ back to top

_.isArrayBuffer

Checks if value is classified as an ArrayBuffer object.

// Lodash
_.isArrayBuffer(new ArrayBuffer(2));
// output: true

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

:warning: You will get the wrong result if you get ArrayBuffer from another realm. See details.

Browser Support for instanceof

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

⬆ back to top

_.join

:heavy_exclamation_mark:Not in Underscore.js Joins a list of elements in an array with a given separator.

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

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

Browser Support for Array.prototype.join()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.last

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

// Underscore/Lodash
const numbers = [1, 2, 3, 4, 5];
_.last(numbers);
// => 5

// Underscore
_.last(numbers, 2);
// => [4, 5]

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

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

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

Browser Support for Array.prototype.concat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.lastIndexOf

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

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

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

Browser Support for Array.prototype.lastIndexOf()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.reverse

:heavy_exclamation_mark:Not in Underscore.js Reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.

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

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

Voice from the Lodash author:

Lodash's _.reverse just calls Array#reverse and enables composition like _.map(arrays, _.reverse). It's exposed on _ because previously, like Underscore, it was only exposed in the chaining syntax. --- jdalton

Browser Support for Array.prototype.reverse()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9 ✔

⬆ back to top

_.slice

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.without

:heavy_exclamation_mark:Not in Underscore.js Returns an array where matching items are filtered.

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

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

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.5 ✔9 ✔

⬆ back to top

_.initial

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

// Underscore
var array = [5, 4, 3, 2, 1]
console.log(_.initial(array, 2))
// output: [5, 4, 3]

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.pull

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

// Lodash
const array = [1, 2, 3, 1, 2, 3];
_.pull(array, 2, 3);
console.log(array); // output: [1, 1]
// Native JS
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]. This is not in place, unlike lodash!
// TypeScript
const array = [1, 2, 3, 1, 2, 3];
const pull = <T extends unknown>(sourceArray: T[], ...removeList: T[]): T[] => {
  const removeSet = new Set(removeList);
  return sourceArray.filter(el => !removeSet.has(el));
};
console.log(pull(array, 2, 3)); // output: [1, 1]
console.log(array); // still [1, 2, 3, 1, 2, 3]. This is not in place, unlike lodash!

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.5 ✔9 ✔

Browser Support for Set.prototype.has()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38 ✔12 ✔13 ✔11 ✔25 ✔8 ✔

⬆ back to top

_.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)

// Lodash
var array1 = [2.1];
var array2 = [1.2, 2.3];
var result = _.unionBy(array1, array2, Math.floor)
console.log(result)
// output: [2.1, 1.2]

// Native
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]

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

Browser Support for Set.prototype.has()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38 ✔12 ✔13 ✔11 ✔25 ✔8 ✔

⬆ back to top

Collection*

:heavy_exclamation_mark:Important: Note that most native equivalents are array methods, and will not work with objects. If this functionality is needed and no object method is provided, then Lodash/Underscore is the better option.

_.each

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

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

//For objects
_.each({'one':1, 'two':2, 'three':3}, function(value) {
  console.log(value)
})
// output: 1 2 3

// Native
//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

Browser Support for Array.prototype.forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

Browser Support for Object.entries().forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54 ✔14 ✔47 ✔41 ✔10.1✔

⬆ back to top

_.every

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

// Underscore/Lodash
function isLargerThanTen (element, index, array) {
  return element >= 10
}
var array = [10, 20, 30]
var result = _.every(array, isLargerThanTen)
console.log(result)
// output: true

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

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

Browser Support fpr Array.prototype.every()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.filter

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

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

// Native
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]

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9 ✔

⬆ back to top

_.groupBy

Group items by key.

// Underscore/Lodash
var grouped = _.groupBy(['one', 'two', 'three'], 'length')
console.log(grouped)
// output: {3: ["one", "two"], 5: ["three"]}

// Native
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"]}
// Underscore/Lodash
var grouped = _.groupBy([1.3, 2.1, 2.4], num => Math.floor(num))
console.log(grouped)
// output: {1: [1.3], 2: [2.1, 2.4]}

// Native
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]}

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.includes

Checks if a value is in collection.

var array = [1, 2, 3]
// Underscore/Lodash - also called _.contains
_.includes(array, 1)
// output: true

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

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

Browser Support for Array.prototype.includes

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
47.0 ✔14.0 ✔43.0 ✔34.0 ✔9.0 ✔

Browser Support for Array.prototype.indexOf

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.keyBy

:heavy_exclamation_mark: Not in Underscore.js Creates an object composed of keys generated from the results of running each element of collection through iteratee.

// Lodash
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({ data: { id: 'a1', title: 'abc' }}, 'id'))
// output: { a1: { id: 'a1', title: 'abc' }}

// keyBy for array only
const keyBy = (array, key) => (array || []).reduce((r, x) => ({ ...r, [key ? x[key] : x]: x }), {});

// Native
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) : Object.values(keyBy(c, key));
}

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12.0 ✔3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.map

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

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

// Native
var array1 = [1, 2, 3]
var array2 = array1.map(function (value, index) {
  return value * 2
})
console.log(array2)
// output: [2, 4, 6]
// Underscore/Lodash
var object1 = { 'a': 1, 'b': 2, 'c': 3 }
var object2 = _.map(object1, function (value, index) {
  return value * 2
})
console.log(object2)
// output: [2, 4, 6]

// Native
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]

Browser Support for Object.entries() and destructuring

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔

Browser Support for Array.prototype.map()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.minBy and _.maxBy

Use Array#reduce for find the maximum or minimum collection item

// Underscore/Lodash
var data = [{ value: 6 }, { value: 2 }, { value: 4 }]
var minItem = _.minBy(data, 'value')
var maxItem = _.maxBy(data, 'value')
console.log(minItem, maxItem)
// output: { value: 2 } { value: 6 }

// Native
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 }

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.pluck

array.map or _.map can also be used to replace _.pluck. Lodash v4.0 removed _.pluck in favor of _.map with iteratee shorthand. Details can be found in Changelog

// Underscore/Lodash
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = _.pluck(array1, "name")
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]

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

Browser Support for Array.prototype.map()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.reduce

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

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

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

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.range

Creates an array of numbers progressing from start up to.

// Underscore/Lodash
_.range(4)  // output: [0, 1, 2, 3]
_.range(-4) // output: [0, -1, -2, -3]
_.range(1, 5)     // output: [1, 2, 3, 4]
_.range(0, 20, 5) // output: [0, 5, 10, 15]

// Native ( solution with 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]

// Native ( solution with 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]

Browser Support for Array.from()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔32.0 ✔9.0 ✔

Browser Support for keys and spread in Array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔7.1 ✔

⬆ back to top

_.reduceRight

This method is like _.reduce except that it iterates over elements of collection from right to left.

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

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

Browser Support for Array.prototype.reduceRight()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.reject

The opposite of _.filter; this method returns the elements of collection that predicate does not return truthy for.

// Underscore/Lodash
var array = [1, 2, 3, 4, 5];
var result = _.reject(array, function (x) {
  return x % 2 === 0;
});
// output: [1, 3, 5]

// Native
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]

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔1.5 ✔9.0 ✔9.5 ✔3.0 ✔

⬆ back to top

_.sample

Gets a random element from array.

// Underscore/Lodash
const array = [0, 1, 2, 3, 4]
const result = _.sample(array)
console.log(result)
// output: 2

// Native
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

Browser Support for Array.prototype.length() and Math.random()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

⬆ back to top

_.size

Returns the number of values in the collection.

// Underscore/Lodash
var result = _.size({one: 1, two: 2, three: 3})
console.log(result)
// output: 3

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

Browser Support for Object.keys()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔12.0 ✔5.0 ✔

⬆ back to top

_.some

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

// Underscore/Lodash
function isLargerThanTen (element, index, array) {
  return element >= 10
}
var array = [10, 9, 8]
var result = _.some(array, isLargerThanTen)
console.log(result)
// output: true

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

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

Browser Support for Array.prototype.some()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔✔ 9.0

⬆ back to top

_.sortBy and _.orderBy

Sorts an array of object based on an object key provided by a parameter (note this is more limited than Underscore/Lodash).

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

// Underscore
_.sortBy(fruits, 'name');
// => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}]

// Lodash
_.orderBy(fruits, ['name'],['asc']);
// => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}]

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

// The native sort modifies the array in place. `_.orderBy` and `_.sortBy` do not, so 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}]

Browser Support for Array.prototype.concat() and Array.prototype.sort()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.uniq

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

// Underscore/Lodash
var array = [1, 2, 1, 4, 1, 3]
var result = _.uniq(array)
console.log(result)
// output: [1, 2, 4, 3]

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

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

Function

_.after

:heavy_exclamation_mark:Note this is an alternative implementation 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']
// Underscore/Lodash
var renderNotes = _.after(notes.length, render)
notes.forEach(function (note) {
  console.log(note)
  renderNotes()
})

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

Browser Support for Array.prototype.forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.bind

Create a new function that calls func with thisArg and args.

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

var objB = {
  x: 67
};

// Underscore/Lodash
var boundOffsetX = _.bind(objA.offsetX, objB, 0);

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

Browser Support for Function.prototype.bind()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
7.0 ✔4.0 ✔9.0 ✔11.6 ✔5.1 ✔

⬆ back to top

_.isFunction

Checks if value is classified as a Function object.

// Lodash
_.isFunction(console.log);
// => true

_.isFunction(/abc/);
// => false

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

isFunction(setTimeout);
// => true

isFunction(123);
// => false

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.debounce

Create a new function that calls func with thisArg and args.

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

// Avoid costly calculations while the window size is in flux.
jQuery(window).on('resize', debounce(calculateLayout, 150));

Browser Support for debounce

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
7.0 ✔4.0 ✔9.0 ✔11.6 ✔5.1 ✔

⬆ back to top

_.partial

Create a new function that calls func with args.

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

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

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

Browser Support for Spread

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.throttle

Create a new function that limits calls to func to once every given timeframe.

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

// Avoid running the same function twice within the specified timeframe.
jQuery(window).on('resize', throttle(calculateLayout, 150));

Browser Support for throttle

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔12.0 ✔3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

Lang

_.castArray

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

// Underscore
console.log(_.castArray(5))
// output: [5]
console.log(_.castArray([2]))
// output: [2]

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

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

⬆ back to top

_.isDate

Checks if value is classified as a Date object.

// Lodash
console.log(_.isDate(new Date));
// output: true

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

Browser Support for String.prototype.toString.call()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.gt

Checks if value is greater than other.

// Lodash
console.log(_.gt(3, 1))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.gte

Checks if value is greater than or equal to other.

// Lodash
console.log(_.gte(3, 1))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isEmpty

Checks if value is an empty object or collection.

:heavy_exclamation_mark:Note that the Native version does not support evaluating a Set or a Map

// Lodash
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

// Native
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

Browser Support for Array.prototype.includes()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
47.0 ✔14.0 ✔43.0 ✔34.0 ✔9.0 ✔

⬆ back to top

_.isFinite

Checks if value is a finite primitive number.

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

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

Browser Support for Number.isFinite()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
19.0 ✔16.0 ✔15.0 ✔9.0 ✔

⬆ back to top

_.isInteger

Checks if value is an integer.

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

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

Browser Support for Number.isInteger()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔16.0 ✔

⬆ back to top

_.isNaN

Checks if a value is NaN.

// Underscore/Lodash
console.log(_.isNaN(NaN))
// output: true

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

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

MDN:

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()

Voice from the Lodash author:

Lodash's _.isNaN is equiv to ES6 Number.isNaN which is different than the global isNaN. --- jdalton

Browser Support for isNaN

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

Browser Support for Number.isNaN

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
25.0 ✔15.0 ✔9.0 ✔

⬆ back to top

_.isNil

:heavy_exclamation_mark:Not in Underscore.js Checks if value is null or undefined.

// Lodash
console.log(_.isNil(null))
// output: true
console.log(_.isNil(NaN))
// output: false
console.log(_.isNil(undefined))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isNull

Checks if value is null or undefined.

// Underscore/Lodash
console.log(_.isNull(null))
// output: true
console.log(_.isNull(void 0))
// output: false

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isUndefined

Checks if value is undefined.

// Underscore/Lodash
console.log(_.isUndefined(a))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1 ✔

⬆ back to top

Object

_.assign

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

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

// Native
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 }

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.defaults

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

// Underscore: _.defaults
// Lodash
const newValues = {a: 3};
const defaultValues = {a: 1, b: 2}
const appliedValues = _.defaults(newValues, defaultValues);
console.log(appliedValues)
// output { a: 3, b: 2 }

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

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.extend

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

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

// Native
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 }

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.has

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

// Lodash
var object = { a: 1, b: 'settings', c: { d: 'test' } };

var hasA = _.has(object, 'a');
var hasCWhichHasD = _.has(object, 'c.d')

console.log(hasA);
// output: true
console.log(hasCWhichHasD);
// output: true

// Native
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

Browser Support for Object .hasOwnProperty

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔5.5 ✔5 ✔3 ✔

⬆ back to top

_.get

Gets the value at path of object. Note: If provided path does not exist inside the object js will generate error.

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

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

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

// Native
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

Browser Support for Object destructing

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
49.0 ✔14.0 ✔41.0 ✔41.0 ✔8.0 ✔

Browser Support for optional chaining ?.

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
80.0 ✔80.0 ✔74.0 ✔67.0 ✔13.1 ✔

Browser Support for nullish coalescing operator ??

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
80.0 ✔80.0 ✔72.0 ✔13.1 ✔

⬆ back to top

_.keys

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

// Underscore/Lodash
var result = _.keys({one: 1, two: 2, three: 3})
console.log(result)
// output: ["one", "two", "three"]

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

Browser Support for Object.keys()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔12.0 ✔5.0 ✔

⬆ back to top

_.omit

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

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

// Underscore/Lodash
var result = _.omit(object, ['a', 'c']);
console.log(result)
// output: { 'b': '2' }

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

Browser Support for Spread in object literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
60.0 ✔55.0 ✔37.0 ✔

⬆ back to top

_.pick

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

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

// Underscore/Lodash
var result = _.pick(object, ['a', 'c']);
console.log(result)
// output: {a: 1, c: 3}

// Native
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}));

// Native
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}

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38.0 ✔13.0 ✔12.0 ✔25.0 ✔7.1 ✔

⬆ back to top

_.pickBy

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

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

// Underscore/Lodash
var result = _.pickBy(object);
console.log(result)
// output: {a: 1, c: 3}

// Native
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}

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
6.0 ✔

⬆ back to top

_.toPairs

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

// Underscore - also called _.pairs
// Lodash - also called _.entries
var result = _.toPairs({one: 1, two: 2, three: 3})
console.log(result)
// output: [["one", 1], ["two", 2], ["three", 3]]

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

Browser Support for Object.entries()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54.0 ✔14.0 ✔47.0 ✔41.0 ✔10.1 ✔

⬆ back to top

_.values

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

// Underscore/Lodash
var result = _.values({one: 1, two: 2, three: 3})
console.log(result)
// output: [1, 2, 3]

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

Browser Support for Object.values()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54.0 ✔14.0 ✔47.0 ✔41.0 ✔10.1 ✔

⬆ back to top

String

_.capitalize

:heavy_exclamation_mark:Not in Underscore.js Converts the first character of string to upper case and the remaining to lower case.

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

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

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.endsWith

:heavy_exclamation_mark:Not in Underscore.js Checks if string ends with the given target string.

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

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

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

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

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

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

Browser Support for String.prototype.endsWith()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔17.0 ✔28.0 ✔9.0 ✔

_.isString

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

// Lodash
_.isString('abc');
// => true

_.isString(123);
// => false

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

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

isString(123);
// => false

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.lowerFirst

:heavy_exclamation_mark:Not in Underscore.js Converts the first character of string to lower case.

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

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

var result = lowerFirst('Fred')
console.log(result)
// output: 'fred'
![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.padStart and _.padEnd

:heavy_exclamation_mark:Not in Underscore.js Pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length.

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

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

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

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

Browser Support for String.prototype.padStart() and String.prototype.padEnd()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
57.0 ✔15.0 ✔48.0 ✔44.0 ✔10.0 ✔

_.repeat

:heavy_exclamation_mark:Not in Underscore.js Repeats the given string n times.

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

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

Browser Support for String.prototype.repeat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔24.0 ✔28.0 ✔9.0 ✔

_.replace

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

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

// Native
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.'

Browser Support for String.prototype.replace()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.split

:heavy_exclamation_mark:Not in Underscore.js Splits string by separator.

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

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

Browser Support for String.prototype.split()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.startsWith

:heavy_exclamation_mark:Not in Underscore.js Checks if string starts with the given target string.

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

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

Browser Support for String.prototype.startsWith()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔17.0 ✔28.0 ✔9.0 ✔

_.template

:heavy_exclamation_mark: Note this is an alternative implementation. Native template literals not escape html.

Create a template function.

// Lodash/Underscore
const compiled = _.template('hello <%= user %>!');
var result = compiled({ 'user': 'fred' });
console.log(result);
// output: 'hello fred'

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

Browser Support for String (template) literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔12.0 ✔34.0 ✔28.0 ✔9.0 ✔

_.toLower

:heavy_exclamation_mark:Not in Underscore.js Lowercases a given string.

// Lodash
var result = _.toLower('FOOBAR')
console.log(result)
// output: 'foobar'

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

Browser Support for String.prototype.toLowerCase()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.toUpper

:heavy_exclamation_mark:Not in Underscore.js Uppercases a given string.

// Lodash
var result = _.toUpper('foobar')
console.log(result)
// output: 'FOOBAR'

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

Browser Support for String.prototype.toUpperCase()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.trim

:heavy_exclamation_mark:Not in Underscore.js Removes the leading and trailing whitespace characters from a string.

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

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

Browser Support for String.prototype.trim()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔3.5 ✔9.0 ✔10.5 ✔5.0 ✔

_.upperFirst

:heavy_exclamation_mark:Not in Underscore.js Uppercases the first letter of a given string

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

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

var result = upperFirst('george')
console.log(result)
// output: 'George'
![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

Reference

_.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.

// Lodash
const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
const result = _.uniqWith(objects, _.isEqual);
console.log(result);
// output: [{ x: 1, y: 2 }, { x: 2, y: 1 }]

// Native
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 }]

Browser Support for Array.prototype.filter() and Array.prototype.findIndex()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔12.0 ✔25.0 ✔32.0 ✔8.0 ✔

Util

_.times

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

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

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

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

Browser Support for Array.from()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔32.0 ✔9.0 ✔

Number

_.clamp

Clamps number within the inclusive lower and upper bounds.

// Lodash
_.clamp(-10, -5, 5);
// => -5

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

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

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

// Native
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

Browser Support for Math.min() and Math.max()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.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 params are swapped to support negative ranges.

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

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

  //Native
  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

Browser Support for Math.min() and Math.max()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.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.

  // Lodash
  _.random(0, 5);
  // => an integer between 0 and 5

  _.random(5);
  // => also an integer between 0 and 5

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

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

  //Native ES6
  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

Browser Support for Math.random()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

Inspired by:

Author: You-dont-need
Source Code: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore 
License: MIT license

#javascript #utilities #native 

What is GEEK

Buddha Community

List Of JavaScript Methods Which You Can Use Natively + ESLint Plugin
Autumn  Blick

Autumn Blick

1598839687

How native is React Native? | React Native vs Native App Development

If you are undertaking a mobile app development for your start-up or enterprise, you are likely wondering whether to use React Native. As a popular development framework, React Native helps you to develop near-native mobile apps. However, you are probably also wondering how close you can get to a native app by using React Native. How native is React Native?

In the article, we discuss the similarities between native mobile development and development using React Native. We also touch upon where they differ and how to bridge the gaps. Read on.

A brief introduction to React Native

Let’s briefly set the context first. We will briefly touch upon what React Native is and how it differs from earlier hybrid frameworks.

React Native is a popular JavaScript framework that Facebook has created. You can use this open-source framework to code natively rendering Android and iOS mobile apps. You can use it to develop web apps too.

Facebook has developed React Native based on React, its JavaScript library. The first release of React Native came in March 2015. At the time of writing this article, the latest stable release of React Native is 0.62.0, and it was released in March 2020.

Although relatively new, React Native has acquired a high degree of popularity. The “Stack Overflow Developer Survey 2019” report identifies it as the 8th most loved framework. Facebook, Walmart, and Bloomberg are some of the top companies that use React Native.

The popularity of React Native comes from its advantages. Some of its advantages are as follows:

  • Performance: It delivers optimal performance.
  • Cross-platform development: You can develop both Android and iOS apps with it. The reuse of code expedites development and reduces costs.
  • UI design: React Native enables you to design simple and responsive UI for your mobile app.
  • 3rd party plugins: This framework supports 3rd party plugins.
  • Developer community: A vibrant community of developers support React Native.

Why React Native is fundamentally different from earlier hybrid frameworks

Are you wondering whether React Native is just another of those hybrid frameworks like Ionic or Cordova? It’s not! React Native is fundamentally different from these earlier hybrid frameworks.

React Native is very close to native. Consider the following aspects as described on the React Native website:

  • Access to many native platforms features: The primitives of React Native render to native platform UI. This means that your React Native app will use many native platform APIs as native apps would do.
  • Near-native user experience: React Native provides several native components, and these are platform agnostic.
  • The ease of accessing native APIs: React Native uses a declarative UI paradigm. This enables React Native to interact easily with native platform APIs since React Native wraps existing native code.

Due to these factors, React Native offers many more advantages compared to those earlier hybrid frameworks. We now review them.

#android app #frontend #ios app #mobile app development #benefits of react native #is react native good for mobile app development #native vs #pros and cons of react native #react mobile development #react native development #react native experience #react native framework #react native ios vs android #react native pros and cons #react native vs android #react native vs native #react native vs native performance #react vs native #why react native #why use react native

Chloe  Butler

Chloe Butler

1667425440

Pdf2gerb: Perl Script Converts PDF Files to Gerber format

pdf2gerb

Perl script converts PDF files to Gerber format

Pdf2Gerb generates Gerber 274X photoplotting and Excellon drill files from PDFs of a PCB. Up to three PDFs are used: the top copper layer, the bottom copper layer (for 2-sided PCBs), and an optional silk screen layer. The PDFs can be created directly from any PDF drawing software, or a PDF print driver can be used to capture the Print output if the drawing software does not directly support output to PDF.

The general workflow is as follows:

  1. Design the PCB using your favorite CAD or drawing software.
  2. Print the top and bottom copper and top silk screen layers to a PDF file.
  3. Run Pdf2Gerb on the PDFs to create Gerber and Excellon files.
  4. Use a Gerber viewer to double-check the output against the original PCB design.
  5. Make adjustments as needed.
  6. Submit the files to a PCB manufacturer.

Please note that Pdf2Gerb does NOT perform DRC (Design Rule Checks), as these will vary according to individual PCB manufacturer conventions and capabilities. Also note that Pdf2Gerb is not perfect, so the output files must always be checked before submitting them. As of version 1.6, Pdf2Gerb supports most PCB elements, such as round and square pads, round holes, traces, SMD pads, ground planes, no-fill areas, and panelization. However, because it interprets the graphical output of a Print function, there are limitations in what it can recognize (or there may be bugs).

See docs/Pdf2Gerb.pdf for install/setup, config, usage, and other info.


pdf2gerb_cfg.pm

#Pdf2Gerb config settings:
#Put this file in same folder/directory as pdf2gerb.pl itself (global settings),
#or copy to another folder/directory with PDFs if you want PCB-specific settings.
#There is only one user of this file, so we don't need a custom package or namespace.
#NOTE: all constants defined in here will be added to main namespace.
#package pdf2gerb_cfg;

use strict; #trap undef vars (easier debug)
use warnings; #other useful info (easier debug)


##############################################################################################
#configurable settings:
#change values here instead of in main pfg2gerb.pl file

use constant WANT_COLORS => ($^O !~ m/Win/); #ANSI colors no worky on Windows? this must be set < first DebugPrint() call

#just a little warning; set realistic expectations:
#DebugPrint("${\(CYAN)}Pdf2Gerb.pl ${\(VERSION)}, $^O O/S\n${\(YELLOW)}${\(BOLD)}${\(ITALIC)}This is EXPERIMENTAL software.  \nGerber files MAY CONTAIN ERRORS.  Please CHECK them before fabrication!${\(RESET)}", 0); #if WANT_DEBUG

use constant METRIC => FALSE; #set to TRUE for metric units (only affect final numbers in output files, not internal arithmetic)
use constant APERTURE_LIMIT => 0; #34; #max #apertures to use; generate warnings if too many apertures are used (0 to not check)
use constant DRILL_FMT => '2.4'; #'2.3'; #'2.4' is the default for PCB fab; change to '2.3' for CNC

use constant WANT_DEBUG => 0; #10; #level of debug wanted; higher == more, lower == less, 0 == none
use constant GERBER_DEBUG => 0; #level of debug to include in Gerber file; DON'T USE FOR FABRICATION
use constant WANT_STREAMS => FALSE; #TRUE; #save decompressed streams to files (for debug)
use constant WANT_ALLINPUT => FALSE; #TRUE; #save entire input stream (for debug ONLY)

#DebugPrint(sprintf("${\(CYAN)}DEBUG: stdout %d, gerber %d, want streams? %d, all input? %d, O/S: $^O, Perl: $]${\(RESET)}\n", WANT_DEBUG, GERBER_DEBUG, WANT_STREAMS, WANT_ALLINPUT), 1);
#DebugPrint(sprintf("max int = %d, min int = %d\n", MAXINT, MININT), 1); 

#define standard trace and pad sizes to reduce scaling or PDF rendering errors:
#This avoids weird aperture settings and replaces them with more standardized values.
#(I'm not sure how photoplotters handle strange sizes).
#Fewer choices here gives more accurate mapping in the final Gerber files.
#units are in inches
use constant TOOL_SIZES => #add more as desired
(
#round or square pads (> 0) and drills (< 0):
    .010, -.001,  #tiny pads for SMD; dummy drill size (too small for practical use, but needed so StandardTool will use this entry)
    .031, -.014,  #used for vias
    .041, -.020,  #smallest non-filled plated hole
    .051, -.025,
    .056, -.029,  #useful for IC pins
    .070, -.033,
    .075, -.040,  #heavier leads
#    .090, -.043,  #NOTE: 600 dpi is not high enough resolution to reliably distinguish between .043" and .046", so choose 1 of the 2 here
    .100, -.046,
    .115, -.052,
    .130, -.061,
    .140, -.067,
    .150, -.079,
    .175, -.088,
    .190, -.093,
    .200, -.100,
    .220, -.110,
    .160, -.125,  #useful for mounting holes
#some additional pad sizes without holes (repeat a previous hole size if you just want the pad size):
    .090, -.040,  #want a .090 pad option, but use dummy hole size
    .065, -.040, #.065 x .065 rect pad
    .035, -.040, #.035 x .065 rect pad
#traces:
    .001,  #too thin for real traces; use only for board outlines
    .006,  #minimum real trace width; mainly used for text
    .008,  #mainly used for mid-sized text, not traces
    .010,  #minimum recommended trace width for low-current signals
    .012,
    .015,  #moderate low-voltage current
    .020,  #heavier trace for power, ground (even if a lighter one is adequate)
    .025,
    .030,  #heavy-current traces; be careful with these ones!
    .040,
    .050,
    .060,
    .080,
    .100,
    .120,
);
#Areas larger than the values below will be filled with parallel lines:
#This cuts down on the number of aperture sizes used.
#Set to 0 to always use an aperture or drill, regardless of size.
use constant { MAX_APERTURE => max((TOOL_SIZES)) + .004, MAX_DRILL => -min((TOOL_SIZES)) + .004 }; #max aperture and drill sizes (plus a little tolerance)
#DebugPrint(sprintf("using %d standard tool sizes: %s, max aper %.3f, max drill %.3f\n", scalar((TOOL_SIZES)), join(", ", (TOOL_SIZES)), MAX_APERTURE, MAX_DRILL), 1);

#NOTE: Compare the PDF to the original CAD file to check the accuracy of the PDF rendering and parsing!
#for example, the CAD software I used generated the following circles for holes:
#CAD hole size:   parsed PDF diameter:      error:
#  .014                .016                +.002
#  .020                .02267              +.00267
#  .025                .026                +.001
#  .029                .03167              +.00267
#  .033                .036                +.003
#  .040                .04267              +.00267
#This was usually ~ .002" - .003" too big compared to the hole as displayed in the CAD software.
#To compensate for PDF rendering errors (either during CAD Print function or PDF parsing logic), adjust the values below as needed.
#units are pixels; for example, a value of 2.4 at 600 dpi = .0004 inch, 2 at 600 dpi = .0033"
use constant
{
    HOLE_ADJUST => -0.004 * 600, #-2.6, #holes seemed to be slightly oversized (by .002" - .004"), so shrink them a little
    RNDPAD_ADJUST => -0.003 * 600, #-2, #-2.4, #round pads seemed to be slightly oversized, so shrink them a little
    SQRPAD_ADJUST => +0.001 * 600, #+.5, #square pads are sometimes too small by .00067, so bump them up a little
    RECTPAD_ADJUST => 0, #(pixels) rectangular pads seem to be okay? (not tested much)
    TRACE_ADJUST => 0, #(pixels) traces seemed to be okay?
    REDUCE_TOLERANCE => .001, #(inches) allow this much variation when reducing circles and rects
};

#Also, my CAD's Print function or the PDF print driver I used was a little off for circles, so define some additional adjustment values here:
#Values are added to X/Y coordinates; units are pixels; for example, a value of 1 at 600 dpi would be ~= .002 inch
use constant
{
    CIRCLE_ADJUST_MINX => 0,
    CIRCLE_ADJUST_MINY => -0.001 * 600, #-1, #circles were a little too high, so nudge them a little lower
    CIRCLE_ADJUST_MAXX => +0.001 * 600, #+1, #circles were a little too far to the left, so nudge them a little to the right
    CIRCLE_ADJUST_MAXY => 0,
    SUBST_CIRCLE_CLIPRECT => FALSE, #generate circle and substitute for clip rects (to compensate for the way some CAD software draws circles)
    WANT_CLIPRECT => TRUE, #FALSE, #AI doesn't need clip rect at all? should be on normally?
    RECT_COMPLETION => FALSE, #TRUE, #fill in 4th side of rect when 3 sides found
};

#allow .012 clearance around pads for solder mask:
#This value effectively adjusts pad sizes in the TOOL_SIZES list above (only for solder mask layers).
use constant SOLDER_MARGIN => +.012; #units are inches

#line join/cap styles:
use constant
{
    CAP_NONE => 0, #butt (none); line is exact length
    CAP_ROUND => 1, #round cap/join; line overhangs by a semi-circle at either end
    CAP_SQUARE => 2, #square cap/join; line overhangs by a half square on either end
    CAP_OVERRIDE => FALSE, #cap style overrides drawing logic
};
    
#number of elements in each shape type:
use constant
{
    RECT_SHAPELEN => 6, #x0, y0, x1, y1, count, "rect" (start, end corners)
    LINE_SHAPELEN => 6, #x0, y0, x1, y1, count, "line" (line seg)
    CURVE_SHAPELEN => 10, #xstart, ystart, x0, y0, x1, y1, xend, yend, count, "curve" (bezier 2 points)
    CIRCLE_SHAPELEN => 5, #x, y, 5, count, "circle" (center + radius)
};
#const my %SHAPELEN =
#Readonly my %SHAPELEN =>
our %SHAPELEN =
(
    rect => RECT_SHAPELEN,
    line => LINE_SHAPELEN,
    curve => CURVE_SHAPELEN,
    circle => CIRCLE_SHAPELEN,
);

#panelization:
#This will repeat the entire body the number of times indicated along the X or Y axes (files grow accordingly).
#Display elements that overhang PCB boundary can be squashed or left as-is (typically text or other silk screen markings).
#Set "overhangs" TRUE to allow overhangs, FALSE to truncate them.
#xpad and ypad allow margins to be added around outer edge of panelized PCB.
use constant PANELIZE => {'x' => 1, 'y' => 1, 'xpad' => 0, 'ypad' => 0, 'overhangs' => TRUE}; #number of times to repeat in X and Y directions

# Set this to 1 if you need TurboCAD support.
#$turboCAD = FALSE; #is this still needed as an option?

#CIRCAD pad generation uses an appropriate aperture, then moves it (stroke) "a little" - we use this to find pads and distinguish them from PCB holes. 
use constant PAD_STROKE => 0.3; #0.0005 * 600; #units are pixels
#convert very short traces to pads or holes:
use constant TRACE_MINLEN => .001; #units are inches
#use constant ALWAYS_XY => TRUE; #FALSE; #force XY even if X or Y doesn't change; NOTE: needs to be TRUE for all pads to show in FlatCAM and ViewPlot
use constant REMOVE_POLARITY => FALSE; #TRUE; #set to remove subtractive (negative) polarity; NOTE: must be FALSE for ground planes

#PDF uses "points", each point = 1/72 inch
#combined with a PDF scale factor of .12, this gives 600 dpi resolution (1/72 * .12 = 600 dpi)
use constant INCHES_PER_POINT => 1/72; #0.0138888889; #multiply point-size by this to get inches

# The precision used when computing a bezier curve. Higher numbers are more precise but slower (and generate larger files).
#$bezierPrecision = 100;
use constant BEZIER_PRECISION => 36; #100; #use const; reduced for faster rendering (mainly used for silk screen and thermal pads)

# Ground planes and silk screen or larger copper rectangles or circles are filled line-by-line using this resolution.
use constant FILL_WIDTH => .01; #fill at most 0.01 inch at a time

# The max number of characters to read into memory
use constant MAX_BYTES => 10 * M; #bumped up to 10 MB, use const

use constant DUP_DRILL1 => TRUE; #FALSE; #kludge: ViewPlot doesn't load drill files that are too small so duplicate first tool

my $runtime = time(); #Time::HiRes::gettimeofday(); #measure my execution time

print STDERR "Loaded config settings from '${\(__FILE__)}'.\n";
1; #last value must be truthful to indicate successful load


#############################################################################################
#junk/experiment:

#use Package::Constants;
#use Exporter qw(import); #https://perldoc.perl.org/Exporter.html

#my $caller = "pdf2gerb::";

#sub cfg
#{
#    my $proto = shift;
#    my $class = ref($proto) || $proto;
#    my $settings =
#    {
#        $WANT_DEBUG => 990, #10; #level of debug wanted; higher == more, lower == less, 0 == none
#    };
#    bless($settings, $class);
#    return $settings;
#}

#use constant HELLO => "hi there2"; #"main::HELLO" => "hi there";
#use constant GOODBYE => 14; #"main::GOODBYE" => 12;

#print STDERR "read cfg file\n";

#our @EXPORT_OK = Package::Constants->list(__PACKAGE__); #https://www.perlmonks.org/?node_id=1072691; NOTE: "_OK" skips short/common names

#print STDERR scalar(@EXPORT_OK) . " consts exported:\n";
#foreach(@EXPORT_OK) { print STDERR "$_\n"; }
#my $val = main::thing("xyz");
#print STDERR "caller gave me $val\n";
#foreach my $arg (@ARGV) { print STDERR "arg $arg\n"; }

Download Details:

Author: swannman
Source Code: https://github.com/swannman/pdf2gerb

License: GPL-3.0 license

#perl 

Lawrence  Lesch

Lawrence Lesch

1659664140

List Of JavaScript Methods Which You Can Use Natively + ESLint Plugin

You don't (may not) need Lodash/Underscore

Lodash and Underscore are great modern JavaScript utility libraries, and they are widely used by Front-end developers. However, when you are targeting modern browsers, you may find out that there are many methods which are already supported natively thanks to ECMAScript5 [ES5] and ECMAScript2015 [ES6]. If you want your project to require fewer dependencies, and you know your target browser clearly, then you may not need Lodash/Underscore.

You are welcome to contribute with more items provided below.

If you are targeting legacy JavaScript engine with those ES5 methods, you can use es5-shim

Please note that, the examples used below are just showing you the native alternative of performing certain tasks. For some functions, Lodash provides you more options than native built-ins. This list is not a 1:1 comparison.

Please send a PR if you want to add or modify the code. No need to open an issue unless it's something big and you want to discuss.

Voice of Developers

Make use of native JavaScript object and array utilities before going big.

—Cody Lindley, Author of jQuery Cookbook and JavaScript Enlightenment

You probably don't need Lodash. Nice List of JavaScript methods which you can use natively.

—Daniel Lamb, Computer Scientist, Technical Reviewer of Secrets of the JavaScript Ninja and Functional Programming in JavaScript

I guess not, but I want it.

—Tero Parviainen, Author of build-your-own-angular

I'll admit, I've been guilty of overusing #lodash. Excellent resource.

—@therebelrobot, Maker of web things, Facilitator for Node.js/io.js

ESLint Plugin    

If you're using ESLint, you can install a plugin that will help you identify places in your codebase where you don't (may not) need Lodash/Underscore.

Install the plugin...

npm install --save-dev eslint-plugin-you-dont-need-lodash-underscore

...then update your config

"extends" : ["plugin:you-dont-need-lodash-underscore/compatible"],

For more information, see Configuring the ESLint Plugin

Important: Note that, while many Lodash methods are null safe (e.g. _.keys, _.entries), this is not necessarily the case for their Native equivalent. If null safety is critical for your application, we suggest that you take extra precautions [e.g. consider using the native Object.keys as Object.keys(value || {})].

Collection*

Important: Note that most native equivalents are array methods, and will not work with objects. If this functionality is needed and no object method is provided, then Lodash/Underscore might be the better option. Bear in mind however, that all iterable objects can easily be converted to an array by use of the spread operator.

Array

_.chunk

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

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

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


// Native

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']]

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.compact

Creates an array with all falsy values removed.

// Underscore/Lodash
_.compact([0, 1, false, 2, '', 3]);

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

Browser Support for array.prototype.filter

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.concat

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

// Underscore/Lodash
var array = [1]
var other = _.concat(array, 2, [3], [[4]])

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

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

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

Browser Support for Array.prototype.concat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.difference

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

// Underscore/Lodash
console.log(_.difference([1, 2, 3, 4, 5], [5, 2, 10]))
// output: [1, 3, 4]

// Native
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]

// ES6
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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.drop

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

// Underscore/Lodash
_.drop([1, 2, 3]);
// => [2, 3]

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.dropRight

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

// Underscore/Lodash
_.dropRight([1, 2, 3]);
// => [1, 2]

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.fill

Fills elements of array with value from start up to, but not including, end. Note that fill is a mutable method in both native and Lodash/Underscore.

// Underscore/Lodash
var array = [1, 2, 3]

_.fill(array, 'a')

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

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

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

// Native
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]

Browser Support for Array.prototype.fill()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔31.0 ✔32.0 ✔8 ✔

⬆ back to top

_.find

Returns the value of the first element in the array that satisfies the provided testing function. Otherwise undefined is returned.

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

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

// Native
var 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'

Browser Support for Array.prototype.find()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔25.0 ✔32.0 ✔7.1 ✔

⬆ back to top

_.findIndex

Returns the index of the first element in the array that satisfies the provided testing function. Otherwise -1 is returned.

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

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

// Native
var 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

Browser Support for Array.prototype.findIndex()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔25.0 ✔32.0 ✔7.1 ✔

⬆ back to top

_.first

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

// Underscore/Lodash
_.first([1, 2, 3, 4, 5]);
// => 1

// Underscore
_.first([1, 2, 3, 4, 5], 2);
// => [1, 2]

// Native
[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

// Native (works even with potentially undefined/null, like _.first)
[].concat(undefined).shift()
// => undefined

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.flatten

Flattens array a single level deep.

// Underscore/Lodash
_.flatten([1, [2, [3, [4]], 5]]);
// => [1, 2, [3, [4]], 5]

// Native
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]

// Native(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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔3.0 ✔9.0 ✔10.5 ✔4 ✔

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.prototype.flatMap()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

⬆ back to top

_.flattenDeep

Recursively flattens array.

// Underscore/Lodash
_.flattenDeep([1, [2, [3, [4]], 5]]);
// => [1, 2, 3, 4, 5]

// Native
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]

// Native(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]

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔16.0 ✔37.0 ✔7.1 ✔

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.prototype.flatMap()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

⬆ back to top

_.fromPairs

Returns an object composed from key-value pairs.

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

// Native
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 }

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

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

Browser Support for Object.fromEntries()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
73.0 ✔79.0 ✔63.0 ✔60 ✔12.1 ✔

⬆ back to top

_.head and _.tail

Gets the first element or all but the first element.

const array = [1, 2, 3]

// Underscore: _.first, _.head, _.take
// Lodash: _.first, _.head
_.head(array)
// output: 1

// Underscore: _.rest, _.tail, _.drop
// Lodash: _.tail
_.tail(array)
// output: [2, 3]


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

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.indexOf

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

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

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

Browser Support for Array.prototype.indexOf()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.intersection

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

// Underscore/Lodash
console.log(_.intersection([1, 2, 3], [101, 2, 1, 10], [2, 1]))
// output: [1, 2]

// Native
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]

// ES6
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]

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.takeRight

Creates a slice of array with n elements taken from the end. :heavy_exclamation_mark: Native slice does not behave entirely the same as the Lodash method. See example below to understand why.

// Underscore/Lodash
_.takeRight([1, 2, 3]);
// => [3]

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

_.takeRight([1, 2, 3], 5);
// => [1, 2, 3]

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

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

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

// Difference in compatibility

// Lodash
_.takeRight([1, 2, 3], 0);
// => []

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.isArray

Returns true if given value is an array.

// Lodash
var array = []
console.log(_.isArray(array))
// output: true

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

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

⬆ back to top

_.isArrayBuffer

Checks if value is classified as an ArrayBuffer object.

// Lodash
_.isArrayBuffer(new ArrayBuffer(2));
// output: true

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

:warning: You will get the wrong result if you get ArrayBuffer from another realm. See details.

Browser Support for instanceof

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

⬆ back to top

_.join

:heavy_exclamation_mark:Not in Underscore.js Joins a list of elements in an array with a given separator.

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

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

Browser Support for Array.prototype.join()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.last

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

// Underscore/Lodash
const numbers = [1, 2, 3, 4, 5];
_.last(numbers);
// => 5

// Underscore
_.last(numbers, 2);
// => [4, 5]

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

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

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

Browser Support for Array.prototype.concat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.lastIndexOf

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

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

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

Browser Support for Array.prototype.lastIndexOf()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.reverse

:heavy_exclamation_mark:Not in Underscore.js Reverses array so that the first element becomes the last, the second element becomes the second to last, and so on.

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

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

Voice from the Lodash author:

Lodash's _.reverse just calls Array#reverse and enables composition like _.map(arrays, _.reverse). It's exposed on _ because previously, like Underscore, it was only exposed in the chaining syntax. --- jdalton

Browser Support for Array.prototype.reverse()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9 ✔

⬆ back to top

_.slice

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

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

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.without

:heavy_exclamation_mark:Not in Underscore.js Returns an array where matching items are filtered.

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

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

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.5 ✔9 ✔

⬆ back to top

_.initial

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

// Underscore
var array = [5, 4, 3, 2, 1]
console.log(_.initial(array, 2))
// output: [5, 4, 3]

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

Browser Support for Array.prototype.slice()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔

⬆ back to top

_.pull

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

// Lodash
const array = [1, 2, 3, 1, 2, 3];
_.pull(array, 2, 3);
console.log(array); // output: [1, 1]
// Native JS
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]. This is not in place, unlike lodash!
// TypeScript
const array = [1, 2, 3, 1, 2, 3];
const pull = <T extends unknown>(sourceArray: T[], ...removeList: T[]): T[] => {
  const removeSet = new Set(removeList);
  return sourceArray.filter(el => !removeSet.has(el));
};
console.log(pull(array, 2, 3)); // output: [1, 1]
console.log(array); // still [1, 2, 3, 1, 2, 3]. This is not in place, unlike lodash!

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.5 ✔9 ✔

Browser Support for Set.prototype.has()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38 ✔12 ✔13 ✔11 ✔25 ✔8 ✔

⬆ back to top

_.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)

// Lodash
var array1 = [2.1];
var array2 = [1.2, 2.3];
var result = _.unionBy(array1, array2, Math.floor)
console.log(result)
// output: [2.1, 1.2]

// Native
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]

Browser Support for Array.prototype.flat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
69 ✔62 ✔56 ✔12 ✔

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

Browser Support for Set.prototype.has()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38 ✔12 ✔13 ✔11 ✔25 ✔8 ✔

⬆ back to top

Collection*

:heavy_exclamation_mark:Important: Note that most native equivalents are array methods, and will not work with objects. If this functionality is needed and no object method is provided, then Lodash/Underscore is the better option.

_.each

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

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

//For objects
_.each({'one':1, 'two':2, 'three':3}, function(value) {
  console.log(value)
})
// output: 1 2 3

// Native
//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

Browser Support for Array.prototype.forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

Browser Support for Object.entries().forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54 ✔14 ✔47 ✔41 ✔10.1✔

⬆ back to top

_.every

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

// Underscore/Lodash
function isLargerThanTen (element, index, array) {
  return element >= 10
}
var array = [10, 20, 30]
var result = _.every(array, isLargerThanTen)
console.log(result)
// output: true

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

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

Browser Support fpr Array.prototype.every()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.filter

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

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

// Native
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]

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9 ✔

⬆ back to top

_.groupBy

Group items by key.

// Underscore/Lodash
var grouped = _.groupBy(['one', 'two', 'three'], 'length')
console.log(grouped)
// output: {3: ["one", "two"], 5: ["three"]}

// Native
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"]}
// Underscore/Lodash
var grouped = _.groupBy([1.3, 2.1, 2.4], num => Math.floor(num))
console.log(grouped)
// output: {1: [1.3], 2: [2.1, 2.4]}

// Native
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]}

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.includes

Checks if a value is in collection.

var array = [1, 2, 3]
// Underscore/Lodash - also called _.contains
_.includes(array, 1)
// output: true

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

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

Browser Support for Array.prototype.includes

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
47.0 ✔14.0 ✔43.0 ✔34.0 ✔9.0 ✔

Browser Support for Array.prototype.indexOf

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.keyBy

:heavy_exclamation_mark: Not in Underscore.js Creates an object composed of keys generated from the results of running each element of collection through iteratee.

// Lodash
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({ data: { id: 'a1', title: 'abc' }}, 'id'))
// output: { a1: { id: 'a1', title: 'abc' }}

// keyBy for array only
const keyBy = (array, key) => (array || []).reduce((r, x) => ({ ...r, [key ? x[key] : x]: x }), {});

// Native
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) : Object.values(keyBy(c, key));
}

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12.0 ✔3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.map

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

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

// Native
var array1 = [1, 2, 3]
var array2 = array1.map(function (value, index) {
  return value * 2
})
console.log(array2)
// output: [2, 4, 6]
// Underscore/Lodash
var object1 = { 'a': 1, 'b': 2, 'c': 3 }
var object2 = _.map(object1, function (value, index) {
  return value * 2
})
console.log(object2)
// output: [2, 4, 6]

// Native
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]

Browser Support for Object.entries() and destructuring

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔

Browser Support for Array.prototype.map()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.minBy and _.maxBy

Use Array#reduce for find the maximum or minimum collection item

// Underscore/Lodash
var data = [{ value: 6 }, { value: 2 }, { value: 4 }]
var minItem = _.minBy(data, 'value')
var maxItem = _.maxBy(data, 'value')
console.log(minItem, maxItem)
// output: { value: 2 } { value: 6 }

// Native
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 }

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.pluck

array.map or _.map can also be used to replace _.pluck. Lodash v4.0 removed _.pluck in favor of _.map with iteratee shorthand. Details can be found in Changelog

// Underscore/Lodash
var array1 = [{name: "Alice"}, {name: "Bob"}, {name: "Jeremy"}]
var names = _.pluck(array1, "name")
console.log(names)
// output: ["Alice", "Bob", "Jeremy"]

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

Browser Support for Array.prototype.map()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.reduce

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

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

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

Browser Support for Array.prototype.reduce()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.range

Creates an array of numbers progressing from start up to.

// Underscore/Lodash
_.range(4)  // output: [0, 1, 2, 3]
_.range(-4) // output: [0, -1, -2, -3]
_.range(1, 5)     // output: [1, 2, 3, 4]
_.range(0, 20, 5) // output: [0, 5, 10, 15]

// Native ( solution with 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]

// Native ( solution with 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]

Browser Support for Array.from()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔32.0 ✔9.0 ✔

Browser Support for keys and spread in Array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔7.1 ✔

⬆ back to top

_.reduceRight

This method is like _.reduce except that it iterates over elements of collection from right to left.

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

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

Browser Support for Array.prototype.reduceRight()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

_.reject

The opposite of _.filter; this method returns the elements of collection that predicate does not return truthy for.

// Underscore/Lodash
var array = [1, 2, 3, 4, 5];
var result = _.reject(array, function (x) {
  return x % 2 === 0;
});
// output: [1, 3, 5]

// Native
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]

Browser Support for Array.prototype.filter()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔1.5 ✔9.0 ✔9.5 ✔3.0 ✔

⬆ back to top

_.sample

Gets a random element from array.

// Underscore/Lodash
const array = [0, 1, 2, 3, 4]
const result = _.sample(array)
console.log(result)
// output: 2

// Native
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

Browser Support for Array.prototype.length() and Math.random()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

⬆ back to top

_.size

Returns the number of values in the collection.

// Underscore/Lodash
var result = _.size({one: 1, two: 2, three: 3})
console.log(result)
// output: 3

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

Browser Support for Object.keys()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔12.0 ✔5.0 ✔

⬆ back to top

_.some

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

// Underscore/Lodash
function isLargerThanTen (element, index, array) {
  return element >= 10
}
var array = [10, 9, 8]
var result = _.some(array, isLargerThanTen)
console.log(result)
// output: true

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

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

Browser Support for Array.prototype.some()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔✔ 9.0

⬆ back to top

_.sortBy and _.orderBy

Sorts an array of object based on an object key provided by a parameter (note this is more limited than Underscore/Lodash).

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

// Underscore
_.sortBy(fruits, 'name');
// => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}]

// Lodash
_.orderBy(fruits, ['name'],['asc']);
// => [{name:"apple", amount: 4}, {name:"banana", amount: 2}, {name:"mango", amount: 1}, {name:"pineapple", amount: 2}]

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

// The native sort modifies the array in place. `_.orderBy` and `_.sortBy` do not, so 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}]

Browser Support for Array.prototype.concat() and Array.prototype.sort()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔1.0 ✔5.5 ✔

⬆ back to top

_.uniq

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

// Underscore/Lodash
var array = [1, 2, 1, 4, 1, 3]
var result = _.uniq(array)
console.log(result)
// output: [1, 2, 4, 3]

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

Browser Support for Spread in array literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

Function

_.after

:heavy_exclamation_mark:Note this is an alternative implementation 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']
// Underscore/Lodash
var renderNotes = _.after(notes.length, render)
notes.forEach(function (note) {
  console.log(note)
  renderNotes()
})

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

Browser Support for Array.prototype.forEach()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.5 ✔9.0 ✔

⬆ back to top

_.bind

Create a new function that calls func with thisArg and args.

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

var objB = {
  x: 67
};

// Underscore/Lodash
var boundOffsetX = _.bind(objA.offsetX, objB, 0);

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

Browser Support for Function.prototype.bind()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
7.0 ✔4.0 ✔9.0 ✔11.6 ✔5.1 ✔

⬆ back to top

_.isFunction

Checks if value is classified as a Function object.

// Lodash
_.isFunction(console.log);
// => true

_.isFunction(/abc/);
// => false

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

isFunction(setTimeout);
// => true

isFunction(123);
// => false

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.debounce

Create a new function that calls func with thisArg and args.

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

// Avoid costly calculations while the window size is in flux.
jQuery(window).on('resize', debounce(calculateLayout, 150));

Browser Support for debounce

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
7.0 ✔4.0 ✔9.0 ✔11.6 ✔5.1 ✔

⬆ back to top

_.partial

Create a new function that calls func with args.

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

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

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

Browser Support for Spread

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
46.0 ✔12.0 ✔16.0 ✔37.0 ✔8.0 ✔

⬆ back to top

_.throttle

Create a new function that limits calls to func to once every given timeframe.

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

// Avoid running the same function twice within the specified timeframe.
jQuery(window).on('resize', throttle(calculateLayout, 150));

Browser Support for throttle

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔12.0 ✔3.0 ✔9.0 ✔10.5 ✔4.0 ✔

⬆ back to top

Lang

_.castArray

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

// Underscore
console.log(_.castArray(5))
// output: [5]
console.log(_.castArray([2]))
// output: [2]

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

Browser Support for Array.isArray()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔10.5 ✔5.0 ✔

⬆ back to top

_.isDate

Checks if value is classified as a Date object.

// Lodash
console.log(_.isDate(new Date));
// output: true

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

Browser Support for String.prototype.toString.call()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.gt

Checks if value is greater than other.

// Lodash
console.log(_.gt(3, 1))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.gte

Checks if value is greater than or equal to other.

// Lodash
console.log(_.gte(3, 1))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isEmpty

Checks if value is an empty object or collection.

:heavy_exclamation_mark:Note that the Native version does not support evaluating a Set or a Map

// Lodash
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

// Native
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

Browser Support for Array.prototype.includes()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
47.0 ✔14.0 ✔43.0 ✔34.0 ✔9.0 ✔

⬆ back to top

_.isFinite

Checks if value is a finite primitive number.

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

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

Browser Support for Number.isFinite()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
19.0 ✔16.0 ✔15.0 ✔9.0 ✔

⬆ back to top

_.isInteger

Checks if value is an integer.

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

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

Browser Support for Number.isInteger()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔16.0 ✔

⬆ back to top

_.isNaN

Checks if a value is NaN.

// Underscore/Lodash
console.log(_.isNaN(NaN))
// output: true

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

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

MDN:

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()

Voice from the Lodash author:

Lodash's _.isNaN is equiv to ES6 Number.isNaN which is different than the global isNaN. --- jdalton

Browser Support for isNaN

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

Browser Support for Number.isNaN

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
25.0 ✔15.0 ✔9.0 ✔

⬆ back to top

_.isNil

:heavy_exclamation_mark:Not in Underscore.js Checks if value is null or undefined.

// Lodash
console.log(_.isNil(null))
// output: true
console.log(_.isNil(NaN))
// output: false
console.log(_.isNil(undefined))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isNull

Checks if value is null or undefined.

// Underscore/Lodash
console.log(_.isNull(null))
// output: true
console.log(_.isNull(void 0))
// output: false

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

⬆ back to top

_.isUndefined

Checks if value is undefined.

// Underscore/Lodash
console.log(_.isUndefined(a))
// output: true

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1 ✔

⬆ back to top

Object

_.assign

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

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

// Native
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 }

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.defaults

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

// Underscore: _.defaults
// Lodash
const newValues = {a: 3};
const defaultValues = {a: 1, b: 2}
const appliedValues = _.defaults(newValues, defaultValues);
console.log(appliedValues)
// output { a: 3, b: 2 }

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

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.extend

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

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

// Native
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 }

Browser Support for Object.assign()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔34.0 ✔32.0 ✔9.0 ✔

⬆ back to top

_.has

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

// Lodash
var object = { a: 1, b: 'settings', c: { d: 'test' } };

var hasA = _.has(object, 'a');
var hasCWhichHasD = _.has(object, 'c.d')

console.log(hasA);
// output: true
console.log(hasCWhichHasD);
// output: true

// Native
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

Browser Support for Object .hasOwnProperty

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
12 ✔5.5 ✔5 ✔3 ✔

⬆ back to top

_.get

Gets the value at path of object. Note: If provided path does not exist inside the object js will generate error.

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

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

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

// Native
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

Browser Support for Object destructing

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
49.0 ✔14.0 ✔41.0 ✔41.0 ✔8.0 ✔

Browser Support for optional chaining ?.

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
80.0 ✔80.0 ✔74.0 ✔67.0 ✔13.1 ✔

Browser Support for nullish coalescing operator ??

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
80.0 ✔80.0 ✔72.0 ✔13.1 ✔

⬆ back to top

_.keys

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

// Underscore/Lodash
var result = _.keys({one: 1, two: 2, three: 3})
console.log(result)
// output: ["one", "two", "three"]

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

Browser Support for Object.keys()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔4.0 ✔9.0 ✔12.0 ✔5.0 ✔

⬆ back to top

_.omit

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

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

// Underscore/Lodash
var result = _.omit(object, ['a', 'c']);
console.log(result)
// output: { 'b': '2' }

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

Browser Support for Spread in object literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
60.0 ✔55.0 ✔37.0 ✔

⬆ back to top

_.pick

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

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

// Underscore/Lodash
var result = _.pick(object, ['a', 'c']);
console.log(result)
// output: {a: 1, c: 3}

// Native
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}));

// Native
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}

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
38.0 ✔13.0 ✔12.0 ✔25.0 ✔7.1 ✔

⬆ back to top

_.pickBy

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

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

// Underscore/Lodash
var result = _.pickBy(object);
console.log(result)
// output: {a: 1, c: 3}

// Native
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}

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
6.0 ✔

⬆ back to top

_.toPairs

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

// Underscore - also called _.pairs
// Lodash - also called _.entries
var result = _.toPairs({one: 1, two: 2, three: 3})
console.log(result)
// output: [["one", 1], ["two", 2], ["three", 3]]

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

Browser Support for Object.entries()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54.0 ✔14.0 ✔47.0 ✔41.0 ✔10.1 ✔

⬆ back to top

_.values

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

// Underscore/Lodash
var result = _.values({one: 1, two: 2, three: 3})
console.log(result)
// output: [1, 2, 3]

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

Browser Support for Object.values()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
54.0 ✔14.0 ✔47.0 ✔41.0 ✔10.1 ✔

⬆ back to top

String

_.capitalize

:heavy_exclamation_mark:Not in Underscore.js Converts the first character of string to upper case and the remaining to lower case.

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

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

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

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.endsWith

:heavy_exclamation_mark:Not in Underscore.js Checks if string ends with the given target string.

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

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

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

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

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

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

Browser Support for String.prototype.endsWith()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔17.0 ✔28.0 ✔9.0 ✔

_.isString

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

// Lodash
_.isString('abc');
// => true

_.isString(123);
// => false

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

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

isString(123);
// => false

Browser Support

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.lowerFirst

:heavy_exclamation_mark:Not in Underscore.js Converts the first character of string to lower case.

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

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

var result = lowerFirst('Fred')
console.log(result)
// output: 'fred'
![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.padStart and _.padEnd

:heavy_exclamation_mark:Not in Underscore.js Pads the current string with another string (multiple times, if needed) until the resulting string reaches the given length.

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

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

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

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

Browser Support for String.prototype.padStart() and String.prototype.padEnd()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
57.0 ✔15.0 ✔48.0 ✔44.0 ✔10.0 ✔

_.repeat

:heavy_exclamation_mark:Not in Underscore.js Repeats the given string n times.

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

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

Browser Support for String.prototype.repeat()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔24.0 ✔28.0 ✔9.0 ✔

_.replace

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

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

// Native
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.'

Browser Support for String.prototype.replace()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.split

:heavy_exclamation_mark:Not in Underscore.js Splits string by separator.

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

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

Browser Support for String.prototype.split()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.startsWith

:heavy_exclamation_mark:Not in Underscore.js Checks if string starts with the given target string.

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

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

Browser Support for String.prototype.startsWith()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔17.0 ✔28.0 ✔9.0 ✔

_.template

:heavy_exclamation_mark: Note this is an alternative implementation. Native template literals not escape html.

Create a template function.

// Lodash/Underscore
const compiled = _.template('hello <%= user %>!');
var result = compiled({ 'user': 'fred' });
console.log(result);
// output: 'hello fred'

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

Browser Support for String (template) literals

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
41.0 ✔12.0 ✔34.0 ✔28.0 ✔9.0 ✔

_.toLower

:heavy_exclamation_mark:Not in Underscore.js Lowercases a given string.

// Lodash
var result = _.toLower('FOOBAR')
console.log(result)
// output: 'foobar'

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

Browser Support for String.prototype.toLowerCase()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.toUpper

:heavy_exclamation_mark:Not in Underscore.js Uppercases a given string.

// Lodash
var result = _.toUpper('foobar')
console.log(result)
// output: 'FOOBAR'

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

Browser Support for String.prototype.toUpperCase()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
1.0 ✔

_.trim

:heavy_exclamation_mark:Not in Underscore.js Removes the leading and trailing whitespace characters from a string.

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

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

Browser Support for String.prototype.trim()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
5.0 ✔3.5 ✔9.0 ✔10.5 ✔5.0 ✔

_.upperFirst

:heavy_exclamation_mark:Not in Underscore.js Uppercases the first letter of a given string

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

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

var result = upperFirst('george')
console.log(result)
// output: 'George'
![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

Reference

_.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.

// Lodash
const objects = [{ 'x': 1, 'y': 2 }, { 'x': 2, 'y': 1 }, { 'x': 1, 'y': 2 }];
const result = _.uniqWith(objects, _.isEqual);
console.log(result);
// output: [{ x: 1, y: 2 }, { x: 2, y: 1 }]

// Native
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 }]

Browser Support for Array.prototype.filter() and Array.prototype.findIndex()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔12.0 ✔25.0 ✔32.0 ✔8.0 ✔

Util

_.times

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

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

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

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

Browser Support for Array.from()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]
45.0 ✔32.0 ✔9.0 ✔

Number

_.clamp

Clamps number within the inclusive lower and upper bounds.

// Lodash
_.clamp(-10, -5, 5);
// => -5

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

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

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

// Native
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

Browser Support for Math.min() and Math.max()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.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 params are swapped to support negative ranges.

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

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

  //Native
  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

Browser Support for Math.min() and Math.max()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

_.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.

  // Lodash
  _.random(0, 5);
  // => an integer between 0 and 5

  _.random(5);
  // => also an integer between 0 and 5

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

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

  //Native ES6
  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

Browser Support for Math.random()

![Chrome][chrome-image]![Edge][edge-image]![Firefox][firefox-image]![IE][ie-image]![Opera][opera-image]![Safari][safari-image]

Inspired by:

Author: You-dont-need
Source Code: https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore 
License: MIT license

#javascript #utilities #native 

HI Python

HI Python

1640973720

Beyonic API Python Example Using Flask, Django, FastAPI

Beyonic API Python Examples.

The beyonic APIs Docs Reference: https://apidocs.beyonic.com/

Discuss Beyonic API on slack

The Beyonic API is a representational state transfer, REST based application programming interface that lets you extend the Beyonic dashboard features into your application and systems, allowing you to build amazing payment experiences.

With the Beyonic API you can:

  • Receive and send money and prepaid airtime.
  • List currencies and networks supported by the Beyonic API.
  • Check whether a bank is supported by the Beyonic API.
  • View your account transactions history.
  • Add, retrieve, list, and update contacts to your Beyonic account.
  • Use webhooks to send notifications to URLs on your server that when specific events occur in your Beyonic account (e.g. payments).

Getting Help

For usage, general questions, and discussions the best place to go to is Beyhive Slack Community, also feel free to clone and edit this repository to meet your project, application or system requirements.

To start using the Beyonic Python API, you need to start by downloading the Beyonic API official Python client library and setting your secret key.

Install the Beyonic API Python Official client library

>>> pip install beyonic

Setting your secrete key.

To set the secrete key install the python-dotenv modeule, Python-dotenv is a Python module that allows you to specify environment variables in traditional UNIX-like “.env” (dot-env) file within your Python project directory, it helps us work with SECRETS and KEYS without exposing them to the outside world, and keep them safe during development too.

Installing python-dotenv modeule

>>> pip install python-dotenv

Creating a .env file to keep our secrete keys.

>>> touch .env

Inside your .env file specify the Beyonic API Token .

.env file

BEYONIC_ACCESS_KEY = "enter your API "

You will get your API Token by clicking your user name on the bottom left of the left sidebar menu in the Beyonic web portal and selecting ‘Manage my account’ from the dropdown menu. The API Token is shown at the very bottom of the page.

getExamples.py

import os 
import beyonic
from dotenv import load_dotenv 

load_dotenv()

myapi = os.environ['BEYONIC_ACCESS_KEY']

beyonic.api_key = myapi 

# Listing account: Working. 
accounts = beyonic.Account.list() 
print(accounts)


#Listing currencies: Not working yet.
'''
supported_currencies = beyonic.Currency.list()
print(supported_currencies)

Supported currencies are: USD, UGX, KES, BXC, GHS, TZS, RWF, ZMW, MWK, BIF, EUR, XAF, GNF, XOF, XOF
'''

#Listing networks: Not working yet.
"""
networks = beyonic.Network.list()
print(networks)
"""

#Listing transactions: Working. 
transactions = beyonic.Transaction.list()
print(transactions) 

#Listing contact: Working. 
mycontacts = beyonic.Contact.list() 
print(mycontacts) 


#Listing events: Not working yet.
'''
events = beyonic.Event.list()
print(events)

Error: AttributeError: module 'beyonic' has no attribute 'Event'
'''

Docker file

FROM python:3.8-slim-buster

COPY . .

COPY ./requirements.txt ./requirements.txt

WORKDIR .

RUN pip install -r requirements.txt

CMD [ "python3", "getExamples.py" ]

Build docker image called demo

>>> docker build -t bey .

Run docker image called demo

>>>docker run -t -i bey 

Now, I’ll create a Docker compose file to run a Docker container using the Docker image we just created.


version: "3.6"
services:
  app:
    build: .
    command: python getExamples.py
    volumes:
      - .:/pythonBeyonicExamples

Now we are going to run the following command from the same directory where the docker-compose.yml file is located. The docker compose up command will start and run the entire app.


docker compose up

Output

NB: The screenshot below might differ according to your account deatils and your transcations in deatils.

docker compose up preview

To stop the container running on daemon mode use the below command.

docker compose stop

Output

docker compose preview

Contributing to this repository. All contributions, bug reports, bug fixes, enhancements, and ideas are welcome, You can get in touch with me on twitter @HarunMbaabu.

Download Details:
Author: HarunMbaabu
Source Code: https://github.com/HarunMbaabu/BeyonicAPI-Python-Examples
License: 

#api #python #flask #django #fastapi 

I am Developer

1597487833

Country State City Drop Down List using Ajax in Laravel

Here, i will show you how to create dynamic depedent country state city dropdown list using ajax in laravel.

Country State City Dropdown List using Ajax in php Laravel

Follow Below given steps to create dynamic dependent country state city dropdown list with jQuery ajax in laravel:

  • Step 1: Install Laravel App
  • Step 2: Add Database Details
  • Step 3: Create Country State City Migration and Model File
  • Step 4: Add Routes For Country State City
  • Step 5: Create Controller For Fetch Country State City
  • Step 6: Create Blade File For Show Dependent Country State City in Dropdown
  • Step 7: Run Development Server

https://www.tutsmake.com/ajax-country-state-city-dropdown-in-laravel/

#how to create dynamic dropdown list using laravel dynamic select box in laravel #laravel-country state city package #laravel country state city drop down #dynamic dropdown country city state list in laravel using ajax #country state city dropdown list using ajax in php laravel #country state city dropdown list using ajax in laravel demo