精心收集的超实用的 JavaScript 代码片段(二)

401402次阅读
没有评论

共计 52480 个字符,预计需要花费 132 分钟才能阅读完成。

提醒:本文最后更新于2024-12-14 04:04,文中所关联的信息可能已发生改变,请知悉!

Browser

View contents

Date

View contents

Function

View contents

Math

View contents

Browser

arrayToHtmlList

Converts the given array elements into <li> tags and appends them to the list of the given id.

Use Array.prototype.map(), document.querySelector(), and an anonymous inner closure to create a list of html tags.

const arrayToHtmlList = (arr, listID) =>
  (el => (
    (el = document.querySelector('#' + listID)),
    (el.innerHTML += arr.map(item => `<li>${item}</li>`).join(''))
  ))();
Examples
arrayToHtmlList(['item 1', 'item 2'], 'myListID');

bottomVisible

Returns true if the bottom of the page is visible, false otherwise.

Use scrollY, scrollHeight and clientHeight to determine if the bottom of the page is visible.

const bottomVisible = () =>
  document.documentElement.clientHeight + window.scrollY >=
  (document.documentElement.scrollHeight || document.documentElement.clientHeight);
Examples
bottomVisible(); // true

copyToClipboard

NOTICE: The same functionality can be easily implemented by using the new asynchronous Clipboard API, which is still experimental but should be used in the future instead of this snippet. Find out more about it here.

Copy a string to the clipboard.
Only works as a result of user action (i.e. inside a click event listener).

Create a new <textarea> element, fill it with the supplied data and add it to the HTML document.
Use Selection.getRangeAt()to store the selected range (if any).
Use document.execCommand('copy') to copy to the clipboard.
Remove the <textarea> element from the HTML document.
Finally, use Selection().addRange() to recover the original selected range (if any).

const copyToClipboard = str => {
  const el = document.createElement('textarea');
  el.value = str;
  el.setAttribute('readonly', '');
  el.style.position = 'absolute';
  el.style.left = '-9999px';
  document.body.appendChild(el);
  const selected =
    document.getSelection().rangeCount > 0 ? document.getSelection().getRangeAt(0) : false;
  el.select();
  document.execCommand('copy');
  document.body.removeChild(el);
  if (selected) {
    document.getSelection().removeAllRanges();
    document.getSelection().addRange(selected);
  }
};
Examples
copyToClipboard('Lorem ipsum'); // 'Lorem ipsum' copied to clipboard.

counter

Creates a counter with the specified range, step and duration for the specified selector.

Check if step has the proper sign and change it accordingly.
Use setInterval() in combination with Math.abs() and Math.floor() to calculate the time between each new text draw.
Use document.querySelector().innerHTML to update the value of the selected element.
Omit the fourth parameter, step, to use a default step of 1.
Omit the fifth parameter, duration, to use a default duration of 2000ms.

const counter = (selector, start, end, step = 1, duration = 2000) => {
  let current = start,
    _step = (end - start) * step < 0 ? -step : step,
    timer = setInterval(() => {
      current += _step;
      document.querySelector(selector).innerHTML = current;
      if (current >= end) document.querySelector(selector).innerHTML = end;
      if (current >= end) clearInterval(timer);
    }, Math.abs(Math.floor(duration / (end - start))));
  return timer;
};
Examples
counter('#my-id', 1, 1000, 5, 2000); // Creates a 2-second timer for the element with id="my-id"

createElement

Creates an element from a string (without appending it to the document).
If the given string contains multiple elements, only the first one will be returned.

Use document.createElement() to create a new element.
Set its innerHTML to the string supplied as the argument.
Use ParentNode.firstElementChild to return the element version of the string.

const createElement = str => {
  const el = document.createElement('div');
  el.innerHTML = str;
  return el.firstElementChild;
};
Examples
const el = createElement(
  `<div class="container">
    <p>Hello!</p>
  </div>`
);
console.log(el.className); // 'container'

createEventHub

Creates a pub/sub (publish–subscribe) event hub with emit, on, and off methods.

Use Object.create(null) to create an empty hub object that does not inherit properties from Object.prototype.
For emit, resolve the array of handlers based on the event argument and then run each one with Array.prototype.forEach() by passing in the data as an argument.
For on, create an array for the event if it does not yet exist, then use Array.prototype.push() to add the handler
to the array.
For off, use Array.prototype.findIndex() to find the index of the handler in the event array and remove it using Array.prototype.splice().

const createEventHub = () => ({
  hub: Object.create(null),
  emit(event, data) {
    (this.hub[event] || []).forEach(handler => handler(data));
  },
  on(event, handler) {
    if (!this.hub[event]) this.hub[event] = [];
    this.hub[event].push(handler);
  },
  off(event, handler) {
    const i = (this.hub[event] || []).findIndex(h => h === handler);
    if (i > -1) this.hub[event].splice(i, 1);
  }
});
Examples
const handler = data => console.log(data);
const hub = createEventHub();
let increment = 0;

// Subscribe: listen for different types of events
hub.on('message', handler);
hub.on('message', () => console.log('Message event fired'));
hub.on('increment', () => increment++);

// Publish: emit events to invoke all handlers subscribed to them, passing the data to them as an argument
hub.emit('message', 'hello world'); // logs 'hello world' and 'Message event fired'
hub.emit('message', { hello: 'world' }); // logs the object and 'Message event fired'
hub.emit('increment'); // `increment` variable is now 1

// Unsubscribe: stop a specific handler from listening to the 'message' event
hub.off('message', handler);

currentURL

Returns the current URL.

Use window.location.href to get current URL.

const currentURL = () => window.location.href;
Examples
currentURL(); // 'https://google.com'

detectDeviceType

Detects wether the website is being opened in a mobile device or a desktop/laptop.

Use a regular expression to test the navigator.userAgent property to figure out if the device is a mobile device or a desktop/laptop.

const detectDeviceType = () =>
  /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)
    ? 'Mobile'
    : 'Desktop';
Examples
detectDeviceType(); // "Mobile" or "Desktop"

elementContains

Returns true if the parent element contains the child element, false otherwise.

Check that parent is not the same element as child, use parent.contains(child) to check if the parent element contains the child element.

const elementContains = (parent, child) => parent !== child && parent.contains(child);
Examples
elementContains(document.querySelector('head'), document.querySelector('title')); // true
elementContains(document.querySelector('body'), document.querySelector('body')); // false

elementIsVisibleInViewport

Returns true if the element specified is visible in the viewport, false otherwise.

Use Element.getBoundingClientRect() and the window.inner(Width|Height) values
to determine if a given element is visible in the viewport.
Omit the second argument to determine if the element is entirely visible, or specify true to determine if
it is partially visible.

const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
  const { top, left, bottom, right } = el.getBoundingClientRect();
  const { innerHeight, innerWidth } = window;
  return partiallyVisible
    ? ((top > 0 && top < innerHeight) || (bottom > 0 && bottom < innerHeight)) &&
        ((left > 0 && left < innerWidth) || (right > 0 && right < innerWidth))
    : top >= 0 && left >= 0 && bottom <= innerHeight && right <= innerWidth;
};
Examples
// e.g. 100x100 viewport and a 10x10px element at position {top: -1, left: 0, bottom: 9, right: 10}
elementIsVisibleInViewport(el); // false - (not fully visible)
elementIsVisibleInViewport(el, true); // true - (partially visible)

getImages

Fetches all images from within an element and puts them into an array

Use Element.prototype.getElementsByTagName() to fetch all <img> elements inside the provided element, Array.prototype.map() to map every src attribute of their respective <img> element, then create a Set to eliminate duplicates and return the array.

const getImages = (el, includeDuplicates = false) => {
  const images = [...el.getElementsByTagName('img')].map(img => img.getAttribute('src'));
  return includeDuplicates ? images : [...new Set(images)];
};
Examples
getImages(document, true); // ['image1.jpg', 'image2.png', 'image1.png', '...']
getImages(document, false); // ['image1.jpg', 'image2.png', '...']

getScrollPosition

Returns the scroll position of the current page.

Use pageXOffset and pageYOffset if they are defined, otherwise scrollLeft and scrollTop.
You can omit el to use a default value of window.

const getScrollPosition = (el = window) => ({
  x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
  y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
});
Examples
getScrollPosition(); // {x: 0, y: 200}

getStyle

Returns the value of a CSS rule for the specified element.

Use Window.getComputedStyle() to get the value of the CSS rule for the specified element.

const getStyle = (el, ruleName) => getComputedStyle(el)[ruleName];
Examples
getStyle(document.querySelector('p'), 'font-size'); // '16px'

hasClass

Returns true if the element has the specified class, false otherwise.

Use element.classList.contains() to check if the element has the specified class.

const hasClass = (el, className) => el.classList.contains(className);
Examples
hasClass(document.querySelector('p.special'), 'special'); // true

hashBrowser

Creates a hash for a value using the SHA-256 algorithm. Returns a promise.

Use the SubtleCrypto API to create a hash for the given value.

const hashBrowser = val =>
  crypto.subtle.digest('SHA-256', new TextEncoder('utf-8').encode(val)).then(h => {
    let hexes = [],
      view = new DataView(h);
    for (let i = 0; i < view.byteLength; i += 4)
      hexes.push(('00000000' + view.getUint32(i).toString(16)).slice(-8));
    return hexes.join('');
  });
Examples
hashBrowser(JSON.stringify({ a: 'a', b: [1, 2, 3, 4], foo: { c: 'bar' } })).then(console.log); // '04aa106279f5977f59f9067fa9712afc4aedc6f5862a8defc34552d8c7206393'

hide

Hides all the elements specified.

Use NodeList.prototype.forEach() to apply display: none to each element specified.

const hide = (...el) => [...el].forEach(e => (e.style.display = 'none'));
Examples
hide(document.querySelectorAll('img')); // Hides all <img> elements on the page

httpsRedirect

Redirects the page to HTTPS if its currently in HTTP. Also, pressing the back button doesn’t take it back to the HTTP page as its replaced in the history.

Use location.protocol to get the protocol currently being used. If it’s not HTTPS, use location.replace() to replace the existing page with the HTTPS version of the page. Use location.href to get the full address, split it with String.prototype.split() and remove the protocol part of the URL.

const httpsRedirect = () => {
  if (location.protocol !== 'https:') location.replace('https://' + location.href.split('//')[1]);
};
Examples
httpsRedirect(); // If you are on http://mydomain.com, you are redirected to https://mydomain.com

insertAfter

Inserts an HTML string after the end of the specified element.

Use el.insertAdjacentHTML() with a position of 'afterend' to parse htmlString and insert it after the end of el.

const insertAfter = (el, htmlString) => el.insertAdjacentHTML('afterend', htmlString);
Examples
insertAfter(document.getElementById('myId'), '<p>after</p>'); // <div id="myId">...</div> <p>after</p>

insertBefore

Inserts an HTML string before the start of the specified element.

Use el.insertAdjacentHTML() with a position of 'beforebegin' to parse htmlString and insert it before the start of el.

const insertBefore = (el, htmlString) => el.insertAdjacentHTML('beforebegin', htmlString);
Examples
insertBefore(document.getElementById('myId'), '<p>before</p>'); // <p>before</p> <div id="myId">...</div>

isBrowserTabFocused

Returns true if the browser tab of the page is focused, false otherwise.

Use the Document.hidden property, introduced by the Page Visibility API to check if the browser tab of the page is visible or hidden.

const isBrowserTabFocused = () => !document.hidden;
Examples
isBrowserTabFocused(); // true

nodeListToArray

Converts a NodeList to an array.

Use spread operator inside new array to convert a NodeList to an array.

const nodeListToArray = nodeList => [...nodeList];
Examples
nodeListToArray(document.childNodes); // [ <!DOCTYPE html>, html ]

observeMutations

Returns a new MutationObserver and runs the provided callback for each mutation on the specified element.

Use a [MutationObserver](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver) to observe mutations on the given element. Use Array.prototype.forEach()to run the callback for each mutation that is observed. Omit the third argument,options, to use the default [options](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver#MutationObserverInit) (all true`).

const observeMutations = (element, callback, options) => {
  const observer = new MutationObserver(mutations => mutations.forEach(m => callback(m)));
  observer.observe(
    element,
    Object.assign(
      {
        childList: true,
        attributes: true,
        attributeOldValue: true,
        characterData: true,
        characterDataOldValue: true,
        subtree: true
      },
      options
    )
  );
  return observer;
};
Examples
const obs = observeMutations(document, console.log); // Logs all mutations that happen on the page
obs.disconnect(); // Disconnects the observer and stops logging mutations on the page

off

Removes an event listener from an element.

Use EventTarget.removeEventListener() to remove an event listener from an element.
Omit the fourth argument opts to use false or specify it based on the options used when the event listener was added.

const off = (el, evt, fn, opts = false) => el.removeEventListener(evt, fn, opts);
Examples
const fn = () => console.log('!');
document.body.addEventListener('click', fn);
off(document.body, 'click', fn); // no longer logs '!' upon clicking on the page

on

Adds an event listener to an element with the ability to use event delegation.

Use EventTarget.addEventListener() to add an event listener to an element. If there is a target property supplied to the options object, ensure the event target matches the target specified and then invoke the callback by supplying the correct this context.
Returns a reference to the custom delegator function, in order to be possible to use with [off](#off). Omit opts` to default to non-delegation behavior and event bubbling.

const on = (el, evt, fn, opts = {}) => {
  const delegatorFn = e => e.target.matches(opts.target) && fn.call(e.target, e);
  el.addEventListener(evt, opts.target ? delegatorFn : fn, opts.options || false);
  if (opts.target) return delegatorFn;
};
Examples
const fn = () => console.log('!');
on(document.body, 'click', fn); // logs '!' upon clicking the body
on(document.body, 'click', fn, { target: 'p' }); // logs '!' upon clicking a `p` element child of the body
on(document.body, 'click', fn, { options: true }); // use capturing instead of bubbling

onUserInputChange

Run the callback whenever the user input type changes (mouse or touch). Useful for enabling/disabling code depending on the input device. This process is dynamic and works with hybrid devices (e.g. touchscreen laptops).

Use two event listeners. Assume mouse input initially and bind a touchstart event listener to the document.
On touchstart, add a mousemove event listener to listen for two consecutive mousemove events firing within 20ms, using performance.now().
Run the callback with the input type as an argument in either of these situations.

const onUserInputChange = callback => {
  let type = 'mouse',
    lastTime = 0;
  const mousemoveHandler = () => {
    const now = performance.now();
    if (now - lastTime < 20)
      (type = 'mouse'), callback(type), document.removeEventListener('mousemove', mousemoveHandler);
    lastTime = now;
  };
  document.addEventListener('touchstart', () => {
    if (type === 'touch') return;
    (type = 'touch'), callback(type), document.addEventListener('mousemove', mousemoveHandler);
  });
};
Examples
onUserInputChange(type => {
  console.log('The user is now using', type, 'as an input method.');
});

prefix

Returns the prefixed version (if necessary) of a CSS property that the browser supports.

Use Array.prototype.findIndex() on an array of vendor prefix strings to test if document.body has one of them defined in its CSSStyleDeclaration object, otherwise return null.
Use String.prototype.charAt() and String.prototype.toUpperCase() to capitalize the property, which will be appended to the vendor prefix string.

const prefix = prop => {
  const capitalizedProp = prop.charAt(0).toUpperCase() + prop.slice(1);
  const prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
  const i = prefixes.findIndex(
    prefix => typeof document.body.style[prefix ? prefix + capitalizedProp : prop] !== 'undefined'
  );
  return i !== -1 ? (i === 0 ? prop : prefixes[i] + capitalizedProp) : null;
};
Examples
prefix('appearance'); // 'appearance' on a supported browser, otherwise 'webkitAppearance', 'mozAppearance', 'msAppearance' or 'oAppearance'

recordAnimationFrames

Invokes the provided callback on each animation frame.

Use recursion.
Provided that running is true, continue invoking window.requestAnimationFrame() which invokes the provided callback.
Return an object with two methods start and stop to allow manual control of the recording.
Omit the second argument, autoStart, to implicitly call start when the function is invoked.

const recordAnimationFrames = (callback, autoStart = true) => {
  let running = true,
    raf;
  const stop = () => {
    running = false;
    cancelAnimationFrame(raf);
  };
  const start = () => {
    running = true;
    run();
  };
  const run = () => {
    raf = requestAnimationFrame(() => {
      callback();
      if (running) run();
    });
  };
  if (autoStart) start();
  return { start, stop };
};
Examples
const cb = () => console.log('Animation frame fired');
const recorder = recordAnimationFrames(cb); // logs 'Animation frame fired' on each animation frame
recorder.stop(); // stops logging
recorder.start(); // starts again
const recorder2 = recordAnimationFrames(cb, false); // `start` needs to be explicitly called to begin recording frames

redirect

Redirects to a specified URL.

Use window.location.href or window.location.replace() to redirect to url.
Pass a second argument to simulate a link click (true – default) or an HTTP redirect (false).

const redirect = (url, asLink = true) =>
  asLink ? (window.location.href = url) : window.location.replace(url);
Examples
redirect('https://google.com');

runAsync

Runs a function in a separate thread by using a Web Worker, allowing long running functions to not block the UI.

Create a new Worker using a Blob object URL, the contents of which should be the stringified version of the supplied function.
Immediately post the return value of calling the function back.
Return a promise, listening for onmessage and onerror events and resolving the data posted back from the worker, or throwing an error.

const runAsync = fn => {
  const worker = new Worker(
    URL.createObjectURL(new Blob([`postMessage((${fn})());`]), {
      type: 'application/javascript; charset=utf-8'
    })
  );
  return new Promise((res, rej) => {
    worker.onmessage = ({ data }) => {
      res(data), worker.terminate();
    };
    worker.onerror = err => {
      rej(err), worker.terminate();
    };
  });
};
Examples
const longRunningFunction = () => {
  let result = 0;
  for (let i = 0; i < 1000; i++)
    for (let j = 0; j < 700; j++) for (let k = 0; k < 300; k++) result = result + i + j + k;

  return result;
};
/*
  NOTE: Since the function is running in a different context, closures are not supported.
  The function supplied to `runAsync` gets stringified, so everything becomes literal.
  All variables and functions must be defined inside.
*/
runAsync(longRunningFunction).then(console.log); // 209685000000
runAsync(() => 10 ** 3).then(console.log); // 1000
let outsideVariable = 50;
runAsync(() => typeof outsideVariable).then(console.log); // 'undefined'

scrollToTop

Smooth-scrolls to the top of the page.

Get distance from top using document.documentElement.scrollTop or document.body.scrollTop.
Scroll by a fraction of the distance from the top. Use window.requestAnimationFrame() to animate the scrolling.

const scrollToTop = () => {
  const c = document.documentElement.scrollTop || document.body.scrollTop;
  if (c > 0) {
    window.requestAnimationFrame(scrollToTop);
    window.scrollTo(0, c - c / 8);
  }
};
Examples
scrollToTop();

setStyle

Sets the value of a CSS rule for the specified element.

Use element.style to set the value of the CSS rule for the specified element to val.

const setStyle = (el, ruleName, val) => (el.style[ruleName] = val);
Examples
setStyle(document.querySelector('p'), 'font-size', '20px'); // The first <p> element on the page will have a font-size of 20px

show

Shows all the elements specified.

Use the spread operator (...) and Array.prototype.forEach() to clear the display property for each element specified.

const show = (...el) => [...el].forEach(e => (e.style.display = ''));
Examples
show(...document.querySelectorAll('img')); // Shows all <img> elements on the page

smoothScroll

Smoothly scrolls the element on which it’s called into the visible area of the browser window.

Use .scrollIntoView method to scroll the element.
Pass { behavior: 'smooth' } to .scrollIntoView so it scrolls smoothly.

const smoothScroll = element =>
  document.querySelector(element).scrollIntoView({
    behavior: 'smooth'
  });
Examples
smoothScroll('#fooBar'); // scrolls smoothly to the element with the id fooBar
smoothScroll('.fooBar'); // scrolls smoothly to the first element with a class of fooBar

toggleClass

Toggle a class for an element.

Use element.classList.toggle() to toggle the specified class for the element.

const toggleClass = (el, className) => el.classList.toggle(className);
Examples
toggleClass(document.querySelector('p.special'), 'special'); // The paragraph will not have the 'special' class anymore

triggerEvent

Triggers a specific event on a given element, optionally passing custom data.

Use new CustomEvent() to create an event from the specified eventType and details.
Use el.dispatchEvent() to trigger the newly created event on the given element.
Omit the third argument, detail, if you do not want to pass custom data to the triggered event.

const triggerEvent = (el, eventType, detail) =>
  el.dispatchEvent(new CustomEvent(eventType, { detail }));
Examples
triggerEvent(document.getElementById('myId'), 'click');
triggerEvent(document.getElementById('myId'), 'click', { username: 'bob' });

UUIDGeneratorBrowser

Generates a UUID in a browser.

Use crypto API to generate a UUID, compliant with RFC4122 version 4.

const UUIDGeneratorBrowser = () =>
  ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
    (c ^ (crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))).toString(16)
  );
Examples
UUIDGeneratorBrowser(); // '7982fcfe-5721-4632-bede-6000885be57d'

Date

dayOfYear

Gets the day of the year from a Date object.

Use new Date() and Date.prototype.getFullYear() to get the first day of the year as a Date object, subtract it from the provided date and divide with the milliseconds in each day to get the result.
Use Math.floor() to appropriately round the resulting day count to an integer.

const dayOfYear = date =>
  Math.floor((date - new Date(date.getFullYear(), 0, 0)) / 1000 / 60 / 60 / 24);
Examples
dayOfYear(new Date()); // 272

formatDuration

Returns the human readable format of the given number of milliseconds.

Divide ms with the appropriate values to obtain the appropriate values for day, hour, minute, second and millisecond.
Use Object.entries() with Array.prototype.filter() to keep only non-zero values.
Use Array.prototype.map() to create the string for each value, pluralizing appropriately.
Use String.prototype.join(', ') to combine the values into a string.

const formatDuration = ms => {
  if (ms < 0) ms = -ms;
  const time = {
    day: Math.floor(ms / 86400000),
    hour: Math.floor(ms / 3600000) % 24,
    minute: Math.floor(ms / 60000) % 60,
    second: Math.floor(ms / 1000) % 60,
    millisecond: Math.floor(ms) % 1000
  };
  return Object.entries(time)
    .filter(val => val[1] !== 0)
    .map(([key, val]) => `${val} ${key}${val !== 1 ? 's' : ''}`)
    .join(', ');
};
Examples
formatDuration(1001); // '1 second, 1 millisecond'
formatDuration(34325055574); // '397 days, 6 hours, 44 minutes, 15 seconds, 574 milliseconds'

getColonTimeFromDate

Returns a string of the form HH:MM:SS from a Date object.

Use Date.prototype.toTimeString() and String.prototype.slice() to get the HH:MM:SS part of a given Date object.

const getColonTimeFromDate = date => date.toTimeString().slice(0, 8);
Examples
getColonTimeFromDate(new Date()); // "08:38:00"

getDaysDiffBetweenDates

Returns the difference (in days) between two dates.

Calculate the difference (in days) between two Date objects.

const getDaysDiffBetweenDates = (dateInitial, dateFinal) =>
  (dateFinal - dateInitial) / (1000 * 3600 * 24);
Examples
getDaysDiffBetweenDates(new Date('2017-12-13'), new Date('2017-12-22')); // 9

getMeridiemSuffixOfInteger

Converts an integer to a suffixed string, adding am or pm based on its value.

Use the modulo operator (%) and conditional checks to transform an integer to a stringified 12-hour format with meridiem suffix.

const getMeridiemSuffixOfInteger = num =>
  num === 0 || num === 24
    ? 12 + 'am'
    : num === 12
      ? 12 + 'pm'
      : num < 12
        ? (num % 12) + 'am'
        : (num % 12) + 'pm';
Examples
getMeridiemSuffixOfInteger(0); // "12am"
getMeridiemSuffixOfInteger(11); // "11am"
getMeridiemSuffixOfInteger(13); // "1pm"
getMeridiemSuffixOfInteger(25); // "1pm"

isAfterDate

Check if a date is after another date.

Use the greater than operator (>) to check if the first date comes after the second one.

const isAfterDate = (dateA, dateB) => dateA > dateB;
Examples
isAfterDate(new Date(2010, 10, 21), new Date(2010, 10, 20)); // true

isBeforeDate

Check if a date is before another date.

Use the less than operator (<) to check if the first date comes before the second one.

const isBeforeDate = (dateA, dateB) => dateA < dateB;
Examples
isBeforeDate(new Date(2010, 10, 20), new Date(2010, 10, 21)); // true

isSameDate

Check if a date is the same as another date.

Use Date.prototype.toISOString() and strict equality checking (===) to check if the first date is the same as the second one.

const isSameDate = (dateA, dateB) => dateA.toISOString() === dateB.toISOString();
Examples
isSameDate(new Date(2010, 10, 20), new Date(2010, 10, 20)); // true

maxDate

Returns the maximum of the given dates.

Use Math.max.apply() to find the maximum date value, new Date() to convert it to a Date object.

const maxDate = (...dates) => new Date(Math.max.apply(null, ...dates));
Examples
const array = [
  new Date(2017, 4, 13),
  new Date(2018, 2, 12),
  new Date(2016, 0, 10),
  new Date(2016, 0, 9)
];
maxDate(array); // 2018-03-11T22:00:00.000Z

minDate

Returns the minimum of the given dates.

Use Math.min.apply() to find the minimum date value, new Date() to convert it to a Date object.

const minDate = (...dates) => new Date(Math.min.apply(null, ...dates));
Examples
const array = [
  new Date(2017, 4, 13),
  new Date(2018, 2, 12),
  new Date(2016, 0, 10),
  new Date(2016, 0, 9)
];
minDate(array); // 2016-01-08T22:00:00.000Z

tomorrow

Results in a string representation of tomorrow’s date.

Use new Date() to get today’s date, adding one day using Date.getDate() and Date.setDate(), and converting the Date object to a string.

const tomorrow = (long = false) => {
  let t = new Date();
  t.setDate(t.getDate() + 1);
  const ret = `${t.getFullYear()}-${String(t.getMonth() + 1).padStart(2, '0')}-${String(
    t.getDate()
  ).padStart(2, '0')}`;
  return !long ? ret : `${ret}T00:00:00`;
};
Examples
tomorrow(); // 2017-12-27 (if current date is 2017-12-26)
tomorrow(true); // 2017-12-27T00:00:00 (if current date is 2017-12-26)

Function

attempt

Attempts to invoke a function with the provided arguments, returning either the result or the caught error object.

Use a try... catch block to return either the result of the function or an appropriate error.

const attempt = (fn, ...args) => {
  try {
    return fn(...args);
  } catch (e) {
    return e instanceof Error ? e : new Error(e);
  }
};
Examples
var elements = attempt(function(selector) {
  return document.querySelectorAll(selector);
}, '>_>');
if (elements instanceof Error) elements = []; // elements = []

bind

Creates a function that invokes fn with a given context, optionally adding any additional supplied parameters to the beginning of the arguments.

Return a function that uses Function.prototype.apply() to apply the given context to fn.
Use Array.prototype.concat() to prepend any additional supplied parameters to the arguments.

const bind = (fn, context, ...boundArgs) => (...args) => fn.apply(context, [...boundArgs, ...args]);
Examples
function greet(greeting, punctuation) {
  return greeting + ' ' + this.user + punctuation;
}
const freddy = { user: 'fred' };
const freddyBound = bind(greet, freddy);
console.log(freddyBound('hi', '!')); // 'hi fred!'

bindKey

Creates a function that invokes the method at a given key of an object, optionally adding any additional supplied parameters to the beginning of the arguments.

Return a function that uses Function.prototype.apply() to bind context[fn] to context.
Use the spread operator (...) to prepend any additional supplied parameters to the arguments.

const bindKey = (context, fn, ...boundArgs) => (...args) =>
  context[fn].apply(context, [...boundArgs, ...args]);
Examples
const freddy = {
  user: 'fred',
  greet: function(greeting, punctuation) {
    return greeting + ' ' + this.user + punctuation;
  }
};
const freddyBound = bindKey(freddy, 'greet');
console.log(freddyBound('hi', '!')); // 'hi fred!'

chainAsync

Chains asynchronous functions.

Loop through an array of functions containing asynchronous events, calling next when each asynchronous event has completed.

const chainAsync = fns => {
  let curr = 0;
  const next = () => fns[curr++](next);
  next();
};
Examples
chainAsync([
  next => {
    console.log('0 seconds');
    setTimeout(next, 1000);
  },
  next => {
    console.log('1 second');
  }
]);

compose

Performs right-to-left function composition.

Use Array.prototype.reduce() to perform right-to-left function composition.
The last (rightmost) function can accept one or more arguments; the remaining functions must be unary.

const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
Examples
const add5 = x => x + 5;
const multiply = (x, y) => x * y;
const multiplyAndAdd5 = compose(
  add5,
  multiply
);
multiplyAndAdd5(5, 2); // 15

composeRight

Performs left-to-right function composition.

Use Array.prototype.reduce() to perform left-to-right function composition.
The first (leftmost) function can accept one or more arguments; the remaining functions must be unary.

const composeRight = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
Examples
const add = (x, y) => x + y;
const square = x => x * x;
const addAndSquare = composeRight(add, square);
addAndSquare(1, 2); // 9

converge

Accepts a converging function and a list of branching functions and returns a function that applies each branching function to the arguments and the results of the branching functions are passed as arguments to the converging function.

Use Array.prototype.map() and Function.prototype.apply() to apply each function to the given arguments.
Use the spread operator (...) to call coverger with the results of all other functions.

const converge = (converger, fns) => (...args) => converger(...fns.map(fn => fn.apply(null, args)));
Examples
const average = converge((a, b) => a / b, [
  arr => arr.reduce((a, v) => a + v, 0),
  arr => arr.length
]);
average([1, 2, 3, 4, 5, 6, 7]); // 4

curry

Curries a function.

Use recursion.
If the number of provided arguments (args) is sufficient, call the passed function fn.
Otherwise, return a curried function fn that expects the rest of the arguments.
If you want to curry a function that accepts a variable number of arguments (a variadic function, e.g. Math.min()), you can optionally pass the number of arguments to the second parameter arity.

const curry = (fn, arity = fn.length, ...args) =>
  arity <= args.length ? fn(...args) : curry.bind(null, fn, arity, ...args);
Examples
curry(Math.pow)(2)(10); // 1024
curry(Math.min, 3)(10)(50)(2); // 2

debounce

Creates a debounced function that delays invoking the provided function until at least ms milliseconds have elapsed since the last time it was invoked.

Each time the debounced function is invoked, clear the current pending timeout with clearTimeout() and use setTimeout() to create a new timeout that delays invoking the function until at least ms milliseconds has elapsed. Use Function.prototype.apply() to apply the this context to the function and provide the necessary arguments.
Omit the second argument, ms, to set the timeout at a default of 0 ms.

const debounce = (fn, ms = 0) => {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => fn.apply(this, args), ms);
  };
};
Examples
window.addEventListener(
  'resize',
  debounce(() => {
    console.log(window.innerWidth);
    console.log(window.innerHeight);
  }, 250)
); // Will log the window dimensions at most every 250ms

defer

Defers invoking a function until the current call stack has cleared.

Use setTimeout() with a timeout of 1ms to add a new event to the browser event queue and allow the rendering engine to complete its work. Use the spread (...) operator to supply the function with an arbitrary number of arguments.

const defer = (fn, ...args) => setTimeout(fn, 1, ...args);
Examples
// Example A:
defer(console.log, 'a'), console.log('b'); // logs 'b' then 'a'

// Example B:
document.querySelector('#someElement').innerHTML = 'Hello';
longRunningFunction(); // Browser will not update the HTML until this has finished
defer(longRunningFunction); // Browser will update the HTML then run the function

delay

Invokes the provided function after wait milliseconds.

Use setTimeout() to delay execution of fn.
Use the spread (...) operator to supply the function with an arbitrary number of arguments.

const delay = (fn, wait, ...args) => setTimeout(fn, wait, ...args);
Examples
delay(
  function(text) {
    console.log(text);
  },
  1000,
  'later'
); // Logs 'later' after one second.

functionName

Logs the name of a function.

Use console.debug() and the name property of the passed method to log the method’s name to the debug channel of the console.

const functionName = fn => (console.debug(fn.name), fn);
Examples
functionName(Math.max); // max (logged in debug channel of console)

hz

Returns the number of times a function executed per second.
hz is the unit for hertz, the unit of frequency defined as one cycle per second.

Use performance.now() to get the difference in milliseconds before and after the iteration loop to calculate the time elapsed executing the function iterations times.
Return the number of cycles per second by converting milliseconds to seconds and dividing it by the time elapsed.
Omit the second argument, iterations, to use the default of 100 iterations.

const hz = (fn, iterations = 100) => {
  const before = performance.now();
  for (let i = 0; i < iterations; i++) fn();
  return (1000 * iterations) / (performance.now() - before);
};
Examples
// 10,000 element array
const numbers = Array(10000)
  .fill()
  .map((_, i) => i);

// Test functions with the same goal: sum up the elements in the array
const sumReduce = () => numbers.reduce((acc, n) => acc + n, 0);
const sumForLoop = () => {
  let sum = 0;
  for (let i = 0; i < numbers.length; i++) sum += numbers[i];
  return sum;
};

// `sumForLoop` is nearly 10 times faster
Math.round(hz(sumReduce)); // 572
Math.round(hz(sumForLoop)); // 4784

memoize

Returns the memoized (cached) function.

Create an empty cache by instantiating a new Map object.
Return a function which takes a single argument to be supplied to the memoized function by first checking if the function’s output for that specific input value is already cached, or store and return it if not. The function keyword must be used in order to allow the memoized function to have its this context changed if necessary.
Allow access to the cache by setting it as a property on the returned function.

const memoize = fn => {
  const cache = new Map();
  const cached = function(val) {
    return cache.has(val) ? cache.get(val) : cache.set(val, fn.call(this, val)) && cache.get(val);
  };
  cached.cache = cache;
  return cached;
};
Examples
// See the `anagrams` snippet.
const anagramsCached = memoize(anagrams);
anagramsCached('javascript'); // takes a long time
anagramsCached('javascript'); // returns virtually instantly since it's now cached
console.log(anagramsCached.cache); // The cached anagrams map

negate

Negates a predicate function.

Take a predicate function and apply the not operator (!) to it with its arguments.

const negate = func => (...args) => !func(...args);
Examples
[1, 2, 3, 4, 5, 6].filter(negate(n => n % 2 === 0)); // [ 1, 3, 5 ]

once

Ensures a function is called only once.

Utilizing a closure, use a flag, called, and set it to true once the function is called for the first time, preventing it from being called again. In order to allow the function to have its this context changed (such as in an event listener), the function keyword must be used, and the supplied function must have the context applied.
Allow the function to be supplied with an arbitrary number of arguments using the rest/spread (...) operator.

const once = fn => {
  let called = false;
  return function(...args) {
    if (called) return;
    called = true;
    return fn.apply(this, args);
  };
};
Examples
const startApp = function(event) {
  console.log(this, event); // document.body, MouseEvent
};
document.body.addEventListener('click', once(startApp)); // only runs `startApp` once upon click

partial

Creates a function that invokes fn with partials prepended to the arguments it receives.

Use the spread operator (...) to prepend partials to the list of arguments of fn.

const partial = (fn, ...partials) => (...args) => fn(...partials, ...args);
Examples
const greet = (greeting, name) => greeting + ' ' + name + '!';
const greetHello = partial(greet, 'Hello');
greetHello('John'); // 'Hello John!'

partialRight

Creates a function that invokes fn with partials appended to the arguments it receives.

Use the spread operator (...) to append partials to the list of arguments of fn.

const partialRight = (fn, ...partials) => (...args) => fn(...args, ...partials);
Examples
const greet = (greeting, name) => greeting + ' ' + name + '!';
const greetJohn = partialRight(greet, 'John');
greetJohn('Hello'); // 'Hello John!'

runPromisesInSeries

Runs an array of promises in series.

Use Array.prototype.reduce() to create a promise chain, where each promise returns the next promise when resolved.

const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
Examples
const delay = d => new Promise(r => setTimeout(r, d));
runPromisesInSeries([() => delay(1000), () => delay(2000)]); // Executes each promise sequentially, taking a total of 3 seconds to complete

sleep

Delays the execution of an asynchronous function.

Delay executing part of an async function, by putting it to sleep, returning a Promise.

const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
Examples
async function sleepyWork() {
  console.log("I'm going to sleep for 1 second.");
  await sleep(1000);
  console.log('I woke up after 1 second.');
}

throttle

Creates a throttled function that only invokes the provided function at most once per every wait milliseconds

Use setTimeout() and clearTimeout() to throttle the given method, fn.
Use Function.prototype.apply() to apply the this context to the function and provide the necessary arguments.
Use Date.now() to keep track of the last time the throttled function was invoked.
Omit the second argument, wait, to set the timeout at a default of 0 ms.

const throttle = (fn, wait) => {
  let inThrottle, lastFn, lastTime;
  return function() {
    const context = this,
      args = arguments;
    if (!inThrottle) {
      fn.apply(context, args);
      lastTime = Date.now();
      inThrottle = true;
    } else {
      clearTimeout(lastFn);
      lastFn = setTimeout(function() {
        if (Date.now() - lastTime >= wait) {
          fn.apply(context, args);
          lastTime = Date.now();
        }
      }, Math.max(wait - (Date.now() - lastTime), 0));
    }
  };
};
Examples
window.addEventListener(
  'resize',
  throttle(function(evt) {
    console.log(window.innerWidth);
    console.log(window.innerHeight);
  }, 250)
); // Will log the window dimensions at most every 250ms

times

Iterates over a callback n times

Use Function.call() to call fn n times or until it returns false.
Omit the last argument, context, to use an undefined object (or the global object in non-strict mode).

const times = (n, fn, context = undefined) => {
  let i = 0;
  while (fn.call(context, i) !== false && ++i < n) {}
};
Examples
var output = '';
times(5, i => (output += i));
console.log(output); // 01234

uncurry

Uncurries a function up to depth n.

Return a variadic function.
Use Array.prototype.reduce() on the provided arguments to call each subsequent curry level of the function.
If the length of the provided arguments is less than n throw an error.
Otherwise, call fn with the proper amount of arguments, using Array.prototype.slice(0, n).
Omit the second argument, n, to uncurry up to depth 1.

const uncurry = (fn, n = 1) => (...args) => {
  const next = acc => args => args.reduce((x, y) => x(y), acc);
  if (n > args.length) throw new RangeError('Arguments too few!');
  return next(fn)(args.slice(0, n));
};
Examples
const add = x => y => z => x + y + z;
const uncurriedAdd = uncurry(add, 3);
uncurriedAdd(1, 2, 3); // 6

unfold

Builds an array, using an iterator function and an initial seed value.

Use a while loop and Array.prototype.push() to call the function repeatedly until it returns false.
The iterator function accepts one argument (seed) and must always return an array with two elements ([value, nextSeed]) or false to terminate.

const unfold = (fn, seed) => {
  let result = [],
    val = [null, seed];
  while ((val = fn(val[1]))) result.push(val[0]);
  return result;
};
Examples
var f = n => (n > 50 ? false : [-n, n + 10]);
unfold(f, 10); // [-10, -20, -30, -40, -50]

when

Tests a value, x, against a predicate function. If true, return fn(x). Else, return x.

Return a function expecting a single value, x, that returns the appropriate value based on pred.

const when = (pred, whenTrue) => x => (pred(x) ? whenTrue(x) : x);
Examples
const doubleEvenNumbers = when(x => x % 2 === 0, x => x * 2);
doubleEvenNumbers(2); // 4
doubleEvenNumbers(1); // 1

Math

approximatelyEqual

Checks if two numbers are approximately equal to each other.

Use Math.abs() to compare the absolute difference of the two values to epsilon.
Omit the third parameter, epsilon, to use a default value of 0.001.

const approximatelyEqual = (v1, v2, epsilon = 0.001) => Math.abs(v1 - v2) < epsilon;
Examples
approximatelyEqual(Math.PI / 2.0, 1.5708); // true

average

Returns the average of two or more numbers.

Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0, divide by the length of the array.

const average = (...nums) => nums.reduce((acc, val) => acc + val, 0) / nums.length;
Examples
average(...[1, 2, 3]); // 2
average(1, 2, 3); // 2

averageBy

Returns the average of an array, after mapping each element to a value using the provided function.

Use Array.prototype.map() to map each element to the value returned by fn, Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0, divide by the length of the array.

const averageBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0) /
  arr.length;
Examples
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 5
averageBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 5

binomialCoefficient

Evaluates the binomial coefficient of two integers n and k.

Use Number.isNaN() to check if any of the two values is NaN.
Check if k is less than 0, greater than or equal to n, equal to 1 or n - 1 and return the appropriate result.
Check if n - k is less than k and switch their values accordingly.
Loop from 2 through k and calculate the binomial coefficient.
Use Math.round() to account for rounding errors in the calculation.

const binomialCoefficient = (n, k) => {
  if (Number.isNaN(n) || Number.isNaN(k)) return NaN;
  if (k < 0 || k > n) return 0;
  if (k === 0 || k === n) return 1;
  if (k === 1 || k === n - 1) return n;
  if (n - k < k) k = n - k;
  let res = n;
  for (let j = 2; j <= k; j++) res *= (n - j + 1) / j;
  return Math.round(res);
};
Examples
binomialCoefficient(8, 2); // 28

clampNumber

Clamps num within the inclusive range specified by the boundary values a and b.

If num falls within the range, return num.
Otherwise, return the nearest number in the range.

const clampNumber = (num, a, b) => Math.max(Math.min(num, Math.max(a, b)), Math.min(a, b));
Examples
clampNumber(2, 3, 5); // 3
clampNumber(1, -1, -5); // -1

degreesToRads

Converts an angle from degrees to radians.

Use Math.PI and the degree to radian formula to convert the angle from degrees to radians.

const degreesToRads = deg => (deg * Math.PI) / 180.0;
Examples
degreesToRads(90.0); // ~1.5708

digitize

Converts a number to an array of digits.

Convert the number to a string, using the spread operator (...) to build an array.
Use Array.prototype.map() and parseInt() to transform each value to an integer.

const digitize = n => [...`${n}`].map(i => parseInt(i));
Examples
digitize(123); // [1, 2, 3]

distance

Returns the distance between two points.

Use Math.hypot() to calculate the Euclidean distance between two points.

const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0);
Examples
distance(1, 1, 2, 3); // 2.23606797749979

elo

Computes the new ratings between two or more opponents using the Elo rating system. It takes an array
of pre-ratings and returns an array containing post-ratings.
The array should be ordered from best performer to worst performer (winner -> loser).

Use the exponent ** operator and math operators to compute the expected score (chance of winning).
of each opponent and compute the new rating for each.
Loop through the ratings, using each permutation to compute the post-Elo rating for each player in a pairwise fashion.
Omit the second argument to use the default kFactor of 32.

const elo = ([...ratings], kFactor = 32, selfRating) => {
  const [a, b] = ratings;
  const expectedScore = (self, opponent) => 1 / (1 + 10 ** ((opponent - self) / 400));
  const newRating = (rating, i) =>
    (selfRating || rating) + kFactor * (i - expectedScore(i ? a : b, i ? b : a));
  if (ratings.length === 2) return [newRating(a, 1), newRating(b, 0)];

  for (let i = 0, len = ratings.length; i < len; i++) {
    let j = i;
    while (j < len - 1) {
      j++;
      [ratings[i], ratings[j]] = elo([ratings[i], ratings[j]], kFactor);
    }
  }
  return ratings;
};
Examples
// Standard 1v1s
elo([1200, 1200]); // [1216, 1184]
elo([1200, 1200], 64); // [1232, 1168]
// 4 player FFA, all same rank
elo([1200, 1200, 1200, 1200]).map(Math.round); // [1246, 1215, 1185, 1154]
/*
For teams, each rating can adjusted based on own team's average rating vs.
average rating of opposing team, with the score being added to their
own individual rating by supplying it as the third argument.
*/

factorial

Calculates the factorial of a number.

Use recursion.
If n is less than or equal to 1, return 1.
Otherwise, return the product of n and the factorial of n - 1.
Throws an exception if n is a negative number.

const factorial = n =>
  n < 0
    ? (() => {
      throw new TypeError('Negative numbers are not allowed!');
    })()
    : n <= 1
      ? 1
      : n * factorial(n - 1);
Examples
factorial(6); // 720

fibonacci

Generates an array, containing the Fibonacci sequence, up until the nth term.

Create an empty array of the specific length, initializing the first two values (0 and 1).
Use Array.prototype.reduce() to add values into the array, using the sum of the last two values, except for the first two.

const fibonacci = n =>
  Array.from({ length: n }).reduce(
    (acc, val, i) => acc.concat(i > 1 ? acc[i - 1] + acc[i - 2] : i),
    []
  );
Examples
fibonacci(6); // [0, 1, 1, 2, 3, 5]

gcd

Calculates the greatest common divisor between two or more numbers/arrays.

The inner _gcd function uses recursion.
Base case is when y equals 0. In this case, return x.
Otherwise, return the GCD of y and the remainder of the division x/y.

const gcd = (...arr) => {
  const _gcd = (x, y) => (!y ? x : gcd(y, x % y));
  return [...arr].reduce((a, b) => _gcd(a, b));
};
Examples
gcd(8, 36); // 4
gcd(...[12, 8, 32]); // 4

geometricProgression

Initializes an array containing the numbers in the specified range where start and end are inclusive and the ratio between two terms is step.
Returns an error if step equals 1.

Use Array.from(), Math.log() and Math.floor() to create an array of the desired length, Array.prototype.map() to fill with the desired values in a range.
Omit the second argument, start, to use a default value of 1.
Omit the third argument, step, to use a default value of 2.

const geometricProgression = (end, start = 1, step = 2) =>
  Array.from({ length: Math.floor(Math.log(end / start) / Math.log(step)) + 1 }).map(
    (v, i) => start * step ** i
  );
Examples
geometricProgression(256); // [1, 2, 4, 8, 16, 32, 64, 128, 256]
geometricProgression(256, 3); // [3, 6, 12, 24, 48, 96, 192]
geometricProgression(256, 1, 4); // [1, 4, 16, 64, 256]

hammingDistance

Calculates the Hamming distance between two values.

Use XOR operator (^) to find the bit difference between the two numbers, convert to a binary string using toString(2).
Count and return the number of 1s in the string, using match(/1/g).

const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length;
Examples
hammingDistance(2, 3); // 1

inRange

Checks if the given number falls within the given range.

Use arithmetic comparison to check if the given number is in the specified range.
If the second parameter, end, is not specified, the range is considered to be from 0 to start.

const inRange = (n, start, end = null) => {
  if (end && start > end) [end, start] = [start, end];
  return end == null ? n >= 0 && n < start : n >= start && n < end;
};
Examples
inRange(3, 2, 5); // true
inRange(3, 4); // true
inRange(2, 3, 5); // false
inRange(3, 2); // false

isDivisible

Checks if the first numeric argument is divisible by the second one.

Use the modulo operator (%) to check if the remainder is equal to 0.

const isDivisible = (dividend, divisor) => dividend % divisor === 0;
Examples
isDivisible(6, 3); // true

isEven

Returns true if the given number is even, false otherwise.

Checks whether a number is odd or even using the modulo (%) operator.
Returns true if the number is even, false if the number is odd.

const isEven = num => num % 2 === 0;
Examples
isEven(3); // false

isNegativeZero

Checks if the given value is equal to negative zero (-0).

Checks whether a passed value is equal to 0 and if 1 divided by the value equals -Infinity.

const isNegativeZero = val => val === 0 && 1 / val === -Infinity;
Examples
isNegativeZero(-0); // true
isNegativeZero(0); // false

isPrime

Checks if the provided integer is a prime number.

Check numbers from 2 to the square root of the given number.
Return false if any of them divides the given number, else return true, unless the number is less than 2.

const isPrime = num => {
  const boundary = Math.floor(Math.sqrt(num));
  for (var i = 2; i <= boundary; i++) if (num % i === 0) return false;
  return num >= 2;
};
Examples
isPrime(11); // true

lcm

Returns the least common multiple of two or more numbers.

Use the greatest common divisor (GCD) formula and the fact that lcm(x,y) = x * y / gcd(x,y) to determine the least common multiple.
The GCD formula uses recursion.

const lcm = (...arr) => {
  const gcd = (x, y) => (!y ? x : gcd(y, x % y));
  const _lcm = (x, y) => (x * y) / gcd(x, y);
  return [...arr].reduce((a, b) => _lcm(a, b));
};
Examples
lcm(12, 7); // 84
lcm(...[1, 3, 4, 5]); // 60

luhnCheck

Implementation of the Luhn Algorithm used to validate a variety of identification numbers, such as credit card numbers, IMEI numbers, National Provider Identifier numbers etc.

Use String.prototype.split(''), Array.prototype.reverse() and Array.prototype.map() in combination with parseInt() to obtain an array of digits.
Use Array.prototype.splice(0,1) to obtain the last digit.
Use Array.prototype.reduce() to implement the Luhn Algorithm.
Return true if sum is divisible by 10, false otherwise.

const luhnCheck = num => {
  let arr = (num + '')
    .split('')
    .reverse()
    .map(x => parseInt(x));
  let lastDigit = arr.splice(0, 1)[0];
  let sum = arr.reduce((acc, val, i) => (i % 2 !== 0 ? acc + val : acc + ((val * 2) % 9) || 9), 0);
  sum += lastDigit;
  return sum % 10 === 0;
};
Examples
luhnCheck('4485275742308327'); // true
luhnCheck(6011329933655299); //  false
luhnCheck(123456789); // false

maxBy

Returns the maximum value of an array, after mapping each element to a value using the provided function.

Use Array.prototype.map() to map each element to the value returned by fn, Math.max() to get the maximum value.

const maxBy = (arr, fn) => Math.max(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));
Examples
maxBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 8
maxBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 8

median

Returns the median of an array of numbers.

Find the middle of the array, use Array.prototype.sort() to sort the values.
Return the number at the midpoint if length is odd, otherwise the average of the two middle numbers.

const median = arr => {
  const mid = Math.floor(arr.length / 2),
    nums = [...arr].sort((a, b) => a - b);
  return arr.length % 2 !== 0 ? nums[mid] : (nums[mid - 1] + nums[mid]) / 2;
};
Examples
median([5, 6, 50, 1, -5]); // 5

minBy

Returns the minimum value of an array, after mapping each element to a value using the provided function.

Use Array.prototype.map() to map each element to the value returned by fn, Math.min() to get the maximum value.

const minBy = (arr, fn) => Math.min(...arr.map(typeof fn === 'function' ? fn : val => val[fn]));
Examples
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 2
minBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 2

percentile

Uses the percentile formula to calculate how many numbers in the given array are less or equal to the given value.

Use Array.prototype.reduce() to calculate how many numbers are below the value and how many are the same value and apply the percentile formula.

const percentile = (arr, val) =>
  (100 * arr.reduce((acc, v) => acc + (v < val ? 1 : 0) + (v === val ? 0.5 : 0), 0)) / arr.length;
Examples
percentile([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 6); // 55

powerset

Returns the powerset of a given array of numbers.

Use Array.prototype.reduce() combined with Array.prototype.map() to iterate over elements and combine into an array containing all combinations.

const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]);
Examples
powerset([1, 2]); // [[], [1], [2], [2, 1]]

primes

Generates primes up to a given number, using the Sieve of Eratosthenes.

Generate an array from 2 to the given number. Use Array.prototype.filter() to filter out the values divisible by any number from 2 to the square root of the provided number.

const primes = num => {
  let arr = Array.from({ length: num - 1 }).map((x, i) => i + 2),
    sqroot = Math.floor(Math.sqrt(num)),
    numsTillSqroot = Array.from({ length: sqroot - 1 }).map((x, i) => i + 2);
  numsTillSqroot.forEach(x => (arr = arr.filter(y => y % x !== 0 || y === x)));
  return arr;
};
Examples
primes(10); // [2,3,5,7]

radsToDegrees

Converts an angle from radians to degrees.

Use Math.PI and the radian to degree formula to convert the angle from radians to degrees.

const radsToDegrees = rad => (rad * 180.0) / Math.PI;
Examples
radsToDegrees(Math.PI / 2); // 90

randomIntArrayInRange

Returns an array of n random integers in the specified range.

Use Array.from() to create an empty array of the specific length, Math.random() to generate a random number and map it to the desired range, using Math.floor() to make it an integer.

const randomIntArrayInRange = (min, max, n = 1) =>
  Array.from({ length: n }, () => Math.floor(Math.random() * (max - min + 1)) + min);
Examples
randomIntArrayInRange(12, 35, 10); // [ 34, 14, 27, 17, 30, 27, 20, 26, 21, 14 ]

randomIntegerInRange

Returns a random integer in the specified range.

Use Math.random() to generate a random number and map it to the desired range, using Math.floor() to make it an integer.

const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min;
Examples
randomIntegerInRange(0, 5); // 2

randomNumberInRange

Returns a random number in the specified range.

Use Math.random() to generate a random value, map it to the desired range using multiplication.

const randomNumberInRange = (min, max) => Math.random() * (max - min) + min;
Examples
randomNumberInRange(2, 10); // 6.0211363285087005

round

Rounds a number to a specified amount of digits.

Use Math.round() and template literals to round the number to the specified number of digits.
Omit the second argument, decimals to round to an integer.

const round = (n, decimals = 0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`);
Examples
round(1.005, 2); // 1.01

sdbm

Hashes the input string into a whole number.

Use String.prototype.split('') and Array.prototype.reduce() to create a hash of the input string, utilizing bit shifting.

const sdbm = str => {
  let arr = str.split('');
  return arr.reduce(
    (hashCode, currentVal) =>
      (hashCode = currentVal.charCodeAt(0) + (hashCode << 6) + (hashCode << 16) - hashCode),
    0
  );
};
Examples
sdbm('name'); // -3521204949

standardDeviation

Returns the standard deviation of an array of numbers.

Use Array.prototype.reduce() to calculate the mean, variance and the sum of the variance of the values, the variance of the values, then
determine the standard deviation.
You can omit the second argument to get the sample standard deviation or set it to true to get the population standard deviation.

const standardDeviation = (arr, usePopulation = false) => {
  const mean = arr.reduce((acc, val) => acc + val, 0) / arr.length;
  return Math.sqrt(
    arr.reduce((acc, val) => acc.concat((val - mean) ** 2), []).reduce((acc, val) => acc + val, 0) /
      (arr.length - (usePopulation ? 0 : 1))
  );
};
Examples
standardDeviation([10, 2, 38, 23, 38, 23, 21]); // 13.284434142114991 (sample)
standardDeviation([10, 2, 38, 23, 38, 23, 21], true); // 12.29899614287479 (population)

sum

Returns the sum of two or more numbers/arrays.

Use Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.

const sum = (...arr) => [...arr].reduce((acc, val) => acc + val, 0);
Examples
sum(1, 2, 3, 4); // 10
sum(...[1, 2, 3, 4]); // 10

sumBy

Returns the sum of an array, after mapping each element to a value using the provided function.

Use Array.prototype.map() to map each element to the value returned by fn, Array.prototype.reduce() to add each value to an accumulator, initialized with a value of 0.

const sumBy = (arr, fn) =>
  arr.map(typeof fn === 'function' ? fn : val => val[fn]).reduce((acc, val) => acc + val, 0);
Examples
sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], o => o.n); // 20
sumBy([{ n: 4 }, { n: 2 }, { n: 8 }, { n: 6 }], 'n'); // 20

sumPower

Returns the sum of the powers of all the numbers from start to end (both inclusive).

Use Array.prototype.fill() to create an array of all the numbers in the target range, Array.prototype.map() and the exponent operator (**) to raise them to power and Array.prototype.reduce() to add them together.
Omit the second argument, power, to use a default power of 2.
Omit the third argument, start, to use a default starting value of 1.

const sumPower = (end, power = 2, start = 1) =>
  Array(end + 1 - start)
    .fill(0)
    .map((x, i) => (i + start) ** power)
    .reduce((a, b) => a + b, 0);
Examples
sumPower(10); // 385
sumPower(10, 3); // 3025
sumPower(10, 3, 5); // 2925

toSafeInteger

Converts a value to a safe integer.

Use Math.max() and Math.min() to find the closest safe value.
Use Math.round() to convert to an integer.

const toSafeInteger = num =>
  Math.round(Math.max(Math.min(num, Number.MAX_SAFE_INTEGER), Number.MIN_SAFE_INTEGER));
Examples
toSafeInteger('3.2'); // 3
toSafeInteger(Infinity); // 9007199254740991

参考的文档:
https://github.com/Chalarangelo/30-seconds-of-code
30SofCode Api

正文完
 0
Chou Neil
版权声明:本文于2019-07-20转载自30 seconds of code,共计52480字。
转载提示:此文章非本站原创文章,若需转载请联系原作者获得转载授权。