Skip to content

Instantly share code, notes, and snippets.

@whatAboutJohn
Last active February 8, 2019 12:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save whatAboutJohn/9aa53f7660350d82d1b69480217fd538 to your computer and use it in GitHub Desktop.
Save whatAboutJohn/9aa53f7660350d82d1b69480217fd538 to your computer and use it in GitHub Desktop.
Utility functions for JS
/**
Fetch nested properties, returns undefined instead of throwing error.
@example
const obj = { deep: { nested: stuff: 1 } }
dig(obj, 'deep.something.something.darkside') #=> undefined
*/
function dig (o, p, c = 0) {
const ps = p.split('.'), cr = ps[c]
return ps.length - 1 === c ? undefined : typeof o[cr] === 'object' && !o[cr] instanceof Array ? dig(o[cr], p, c + 1) : o[cr]
}
/**
Loops n number of times and runs a method by passing the current index as parameter.
@example
(3).times(n => n * 2) #=> [2, 4, 6]
*/
Number.prototype.times = function (fn) {
const loop = (c, arr = []) => c ? loop(c - 1, [].concat(fn(c), arr)) : arr
return loop(this.valueOf())
}
/**
Splits array into two. First half if true and second half if false.
@example
[1, 2, 3, 4, 5].split(n => n > 2) #=> [[3, 4, 5], [1, 2]]
*/
Array.prototype.split = function (fn) {
const _a = this.valueOf()
return [_a.filter(i => fn(i)), _a.filter(i => !fn(i))]
/*
return (function _split (_t, _f, i) { return i >= _a.length ? [_t, _f] :
fn(_a[i]) ? _split([].concat(_t, _a[i]), _f, i+1) : _split(_t, [].concat(_f, _a[i]), i+1)
})([], [], 0) */
}
/**
Returns multiple arrays with values sorted based on the conditions provided.
@example
[9, 3, 34, 74, 11, 99].categorize([
n => n <= 10,
n => n <= 50 && n > 10,
n => n >= 50
])
#=> [[9, 3], [34, 11], [74, 99]]
*/
Array.prototype.categorize = function (fns) {
const arr = this.valueOf()
return fns.map(fn => arr.filter(item => fn(item)))
}
/**
Check if argument is an object.
@example
Object.isObject({}) #=> true
*/
Object.prototype.isObject = obj => !!(typeof obj !== 'object' ? 0 : obj instanceof Array ? 0 : 1)
/**
Ruby's tap method for arrays.
@example
[{ name: 'Rick', done: false }, { name: 'Morty', done: true }]
.filter(user => !user.done)
.tap(sendUsersSMS) #=> [{ name: 'Rick' }]
.map(flagUserAsDone)
*/
Array.prototype.tap = function (fn) {
fn(this.valueOf().slice())
return this.valueOf()
}
/**
Returns an array of numbers in between the range of both parameters starting and ending at the exact numbers given.
@example
Array.range(5, 10) #=> [5, 6, 7, 8, 9, 10]
*/
Array.range = function (n1, n2) {
return Array.from(new Array((n2 + 1) - n1).fill(n1), (n1, n2) => n1 + n2, 1)
}
/**
Filter objects by boolean
@example
[{ id: 0, active: true }, { id: 1, active: false }].filterBy('active') #=> [{ id: 0, active: true }]
*/
Array.prototype.filterBy = function (prop) {
return this.valueOf().filter(v => !!v[prop])
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment