Last active
September 15, 2023 12:12
-
-
Save bendc/9b05735dfa6966859025 to your computer and use it in GitHub Desktop.
A set of pure ES2015 functions aimed to make functional JavaScript more idiomatic.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// array utils | |
// ================================================================================================= | |
const combine = (...arrays) => [].concat(...arrays); | |
const compact = arr => arr.filter(Boolean); | |
const contains = (() => Array.prototype.includes | |
? (arr, value) => arr.includes(value) | |
: (arr, value) => arr.some(el => el === value) | |
)(); | |
const difference = (arr, ...others) => { | |
var combined = [].concat(...others) | |
return arr.filter(el => !combined.some(exclude => el === exclude)) | |
}; | |
const head = arr => arr[0]; | |
const initial = arr => arr.slice(0, -1); | |
const intersection = (...arrays) => | |
[...Set([].concat(...arrays))].filter(toFind => | |
arrays.every(arr => arr.some(el => el === toFind)) | |
); | |
const last = arr => arr.slice(-1)[0]; | |
const sortedIndex = (arr, value) => | |
[value].concat(arr).sort().indexOf(value); | |
const tail = arr => arr.slice(1); | |
const toArray = (() => Array.from ? Array.from : obj => [].slice.call(obj))(); | |
const union = (...arrays) => [...Set([].concat(...arrays))]; | |
const unique = arr => [...Set(arr)]; | |
const without = (arr, ...values) => | |
arr.filter(el => !values.some(exclude => el === exclude)); | |
// object utils | |
// ================================================================================================= | |
const getValues = obj => Object.keys(obj).map(key => obj[key]); | |
const merge = (() => { | |
const extend = Object.assign ? Object.assign : (target, ...sources) => { | |
sources.forEach(source => | |
Object.keys(source).forEach(prop => target[prop] = source[prop]) | |
); | |
return target; | |
}; | |
return (...objects) => extend({}, ...objects); | |
})(); | |
const toMap = (() => { | |
const convert = obj => new Map(Object.keys(obj).map(key => [key, obj[key]])); | |
return obj => obj instanceof Map ? obj : convert(obj); | |
})(); | |
// math | |
// ================================================================================================= | |
const min = arr => Math.min(...arr); | |
const max = arr => Math.max(...arr); | |
const sum = arr => arr.reduce((a, b) => a + b); | |
const product = arr => arr.reduce((a, b) => a * b); | |
// function decorators | |
// ================================================================================================= | |
const not = fn => (...args) => !fn(...args); | |
const maybe = fn => | |
(...args) => { | |
if (args.length < fn.length || args.some(arg => arg == null)) return; | |
return fn(...args); | |
}; | |
const once = fn => { | |
var done = false; | |
return (...args) => { | |
if (done) return; | |
done = true; | |
fn(...args); | |
}; | |
}; | |
const curry = fn => { | |
const arity = fn.length; | |
const curried = (...args) => | |
args.length < arity ? (...more) => curried(...args, ...more) : fn(...args); | |
return curried; | |
}; | |
const pipeline = (...funcs) => | |
value => funcs.reduce((a, b) => b(a), value); |
combine
seems kind of ill-written given that Array#concat has always accepted multiple arrays. What about:
combine = (...a) => [].concat(...a)
@webbedspace: You're absolutely right, just updated the code. Thanks!
@nfroidure That’s the identity function. noop
implies a function that doesn’t do anything (not even returning a value), e.g. const noop = () => {};
.
@mathiasbynens right! thanks for the correction
Why is head:
const head = arr
=> arr[0]
and last not:
const last = arr => arr[arr.length - 1]
FYI: assign should eventually be shimmed via Object.getOwnPropertySymbols
which might be there, but not necessarily in browsers that support assign too.
Most of these have horrible asymptotic performance.
compact
could be shortened to:
const identity = x => x
const compact = arr => arr.filter(identity)
Or even
const compact = arr => arr.filter(Boolean)
@joeybaker: Cleaner indeed, updated! Thanks :)
you sir ! are a legend.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Added noop https://gist.github.com/nfroidure/00e0ef49433809abe13b it's often useful