1. 1. 目录
    1. 1.1. Array
    2. 1.2. Browser
    3. 1.3. Date
    4. 1.4. Function
    5. 1.5. Math
    6. 1.6. Media
    7. 1.7. Node
    8. 1.8. Object
    9. 1.9. String
    10. 1.10. Utility
  2. 2. Array
    1. 2.1. arrayMax
    2. 2.2. arrayMin
    3. 2.3. chunk
    4. 2.4. compact
    5. 2.5. countOccurrences
    6. 2.6. deepFlatten
    7. 2.7. difference
    8. 2.8. distinctValuesOfArray
    9. 2.9. dropElements
    10. 2.10. everyNth
    11. 2.11. filterNonUnique
    12. 2.12. flatten
    13. 2.13. flattenDepth
    14. 2.14. groupBy
    15. 2.15. head
    16. 2.16. initial
    17. 2.17. initializeArrayWithRange
    18. 2.18. initializeArrayWithValues
    19. 2.19. intersection
    20. 2.20. last
    21. 2.21. mapObject
    22. 2.22. nthElement
    23. 2.23. pick
    24. 2.24. pull
    25. 2.25. remove
    26. 2.26. sample
    27. 2.27. shuffle
    28. 2.28. similarity
    29. 2.29. symmetricDifference
    30. 2.30. tail
    31. 2.31. take
    32. 2.32. takeRight
    33. 2.33. union
    34. 2.34. without
    35. 2.35. zip
  3. 3. Browser
    1. 3.1. bottomVisible
    2. 3.2. currentURL
    3. 3.3. elementIsVisibleInViewport
    4. 3.4. getScrollPosition
    5. 3.5. getURLParameters
    6. 3.6. redirect
    7. 3.7. scrollToTop
  4. 4. Date
    1. 4.1. getDaysDiffBetweenDates
    2. 4.2. JSONToDate
    3. 4.3. toEnglishDate
  5. 5. Function
    1. 5.1. chainAsync
    2. 5.2. compose
    3. 5.3. curry
    4. 5.4. functionName
    5. 5.5. pipe
    6. 5.6. promisify
    7. 5.7. runPromisesInSeries
    8. 5.8. sleep
  6. 6. Math
    1. 6.1. arrayAverage
    2. 6.2. arraySum
    3. 6.3. collatz
    4. 6.4. digitize
    5. 6.5. distance
    6. 6.6. factorial
    7. 6.7. fibonacci
    8. 6.8. gcd
    9. 6.9. hammingDistance
    10. 6.10. isDivisible
    11. 6.11. isEven
    12. 6.12. lcm
    13. 6.13. median
    14. 6.14. palindrome
    15. 6.15. percentile
    16. 6.16. powerset
    17. 6.17. randomIntegerInRange
    18. 6.18. randomNumberInRange
    19. 6.19. round
    20. 6.20. standardDeviation
  7. 7. Media
    1. 7.1. speechSynthesis
  8. 8. Node
    1. 8.1. JSONToFile
    2. 8.2. readFileLines
  9. 9. Object
    1. 9.1. cleanObj
    2. 9.2. objectFromPairs
    3. 9.3. objectToPairs
    4. 9.4. shallowClone
    5. 9.5. truthCheckCollection
  10. 10. String
    1. 10.1. anagrams
    2. 10.2. Capitalize
    3. 10.3. capitalizeEveryWord
    4. 10.4. escapeRegExp
    5. 10.5. fromCamelCase
    6. 10.6. reverseString
    7. 10.7. sortCharactersInString
    8. 10.8. toCamelCase
    9. 10.9. truncateString
  11. 11. Utility
    1. 11.1. coalesce
    2. 11.2. coalesceFactory
    3. 11.3. extendHex
    4. 11.4. getType
    5. 11.5. hexToRGB
    6. 11.6. isArray
    7. 11.7. isBoolean
    8. 11.8. isFunction
    9. 11.9. isNumber
    10. 11.10. isString
    11. 11.11. isSymbol
    12. 11.12. RGBToHex
    13. 11.13. timeTaken
    14. 11.14. toOrdinalSuffix
    15. 11.15. UUIDGenerator
    16. 11.16. validateEmail
    17. 11.17. validateNumber
  12. 12. Credits

Javascript代码段合集

img

花30秒或者更短的时间就能理解的Javascript代码段

  • 可以使用Ctrl + F 或者 command + F搜索
  • 代码段使用ES6编写,使用 Babel transpiler 保证兼容.
  • 作者在持续更新传送门

目录

Array

Browser

Date

Function

Math

Media

Node

Object

String

Utility

Array

arrayMax

返回数组中的最大值.

使用 Math.max() 配合展开操作符 (...) 得到数组中的最大值.

1
2
const arrayMax = arr => Math.max(...arr);
// arrayMax([10, 1, 5]) -> 10

⬆ back to top

arrayMin

返回数组中的最小值.

使用 Math.min() 配合展开操作符 (...) 得到数组中的最小值.

1
2
const arrayMin = arr => Math.min(...arr);
// arrayMin([10, 1, 5]) -> 1

⬆ back to top

chunk

将一个数组分割成几个数组段.

使用 Array.from() 创建一个适合它长度的新的数组
使用 Array.slice() 分割为指定 size 长度的数组段
如果指定的数组不能被平均分割,最后的块将包含剩余的元素。

1
2
3
const chunk = (arr, size) =>
Array.from({length: Math.ceil(arr.length / size)}, (v, i) => arr.slice(i * size, i * size + size));
// chunk([1,2,3,4,5], 2) -> [[1,2],[3,4],[5]]

⬆ back to top

compact

移除数组中的非真值

使用 Array.filter() 过滤非真值 (false, null, 0, "", undefined, 和 NaN).

1
2
const compact = (arr) => arr.filter(Boolean);
// compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ]

⬆ back to top

countOccurrences

计算元素出现的次数.

使用 Array.reduce() 计算指定元素在数组中出现的次数

1
2
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0);
// countOccurrences([1,1,2,1,2,3], 1) -> 3

⬆ back to top

deepFlatten

深度降维

使用递归.
使用 Array.concat() 和一个空数组 ([]) 还有展开运算符 (...) 降维一个多维数组.

1
2
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v));
// deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5]

⬆ back to top

difference

返回两个数组的差集

创建一个 bSet, 然后使用 Array.filter() 查找 a 中不包含 b的元素.

1
2
const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); };
// difference([1,2,3], [1,2,4]) -> [3]

⬆ back to top

distinctValuesOfArray

返回数组中不重复的元素

使用 ES6的 Set 和展开运算符 ...rest 过滤重复的元素.

1
2
const distinctValuesOfArray = arr => [...new Set(arr)];
// distinctValuesOfArray([1,2,2,3,4,4,5]) -> [1,2,3,4,5]

⬆ back to top

dropElements

给函数传递一个表达式和数组,只保留表达式为true的元素

1
2
3
4
5
const dropElements = (arr, func) => {
while (arr.length > 0 && !func(arr[0])) arr.shift();
return arr;
};
// dropElements([1, 2, 3, 4], n => n >= 3) -> [3,4]

⬆ back to top

everyNth

返回数组中每一个第n的元素.

使用 Array.filter() 返回每一个第n的元素.

1
2
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === 0);
// everyNth([1,2,3,4,5,6], 2) -> [ 1, 3, 5 ]

⬆ back to top

filterNonUnique

过滤不唯一的元素.

使用 Array.filter() 只保留唯一的元素.

1
2
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i));
// filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5]

⬆ back to top

flatten

降维数组.

使用 Array.reduce() 获取到每一个元素然后使用 concat() 降维.

1
2
const flatten = arr => arr.reduce((a, v) => a.concat(v), []);
// flatten([1,[2],3,4]) -> [1,2,3,4]

⬆ back to top

flattenDepth

根据指定的深度降维数组.

使用递归,为所有维度的数组降低一维.
使用 Array.reduce()Array.concat() 合并降维后的数组或元素.
此时如果 depth1 停止递归.

1
2
3
4
const flattenDepth = (arr, depth = 1) =>
depth != 1 ? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flattenDepth(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(v), []);
// flattenDepth([1,[2],[[[3],4],5]], 2) -> [1,2,[3],4,5]

⬆ back to top

groupBy

根据指定的表达式为数组分组

使用 Array.map() 映射为根据表达式或属性名值计算后的数组
使用 Array.reduce() 创建一个键值是上一步map出来的结果,值是相对应的数组的对象

1
2
3
4
5
const groupBy = (arr, func) =>
arr.map(typeof func === 'function' ? func : val => val[func])
.reduce((acc, val, i) => { acc[val] = (acc[val] || []).concat(arr[i]); return acc; }, {});
// groupBy([6.1, 4.2, 6.3], Math.floor) -> {4: [4.2], 6: [6.1, 6.3]}
// groupBy(['one', 'two', 'three'], 'length') -> {3: ['one', 'two'], 5: ['three']}

⬆ back to top

返回集合的第一个元素

使用 arr[0] 返回给定数组的第一个元素.

1
2
const head = arr => arr[0];
// head([1,2,3]) -> 1

⬆ back to top

initial

返回一个数组中除去最后一个元素的其他元素.

使用 arr.slice(0,-1) 返回除去最后一个元素的其他元素.

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

⬆ back to top

initializeArrayWithRange

初始化一个指定范围的数组

使用 Array(end-start) 创建一个期望长度的数组, 根据给定的范围使用Array.map()填充数组.
参数start 默认值为 0.

1
2
3
const initializeArrayWithRange = (end, start = 0) =>
Array.from({ length: end - start }).map((v, i) => i + start);
// initializeArrayWithRange(5) -> [0,1,2,3,4]

⬆ back to top

initializeArrayWithValues

初始化并且根据给定的值填充数组.

使用 Array(n) 创建一个期望长度的数组, 根据给定的值使用 fill(v) 填充数组.
参数 value 默认值为 0.

1
2
const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value);
// initializeArrayWithValues(5, 2) -> [2,2,2,2,2]

⬆ back to top

intersection

返回两个数组的交集.

创建一个 bSet, 然后使用 aArray.filter() 查找含 b 元素.

1
2
const intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x)); };
// intersection([1,2,3], [4,3,2]) -> [2,3]

⬆ back to top

last

返回数组中的最后一个元素.

使用 arr.length - 1 计算出最后一个元素的索引,然后返回它的值.

1
2
const last = arr => arr[arr.length - 1];
// last([1,2,3]) -> 3

⬆ back to top

mapObject

映射一个数组,结果是键值为他的每一个元素的值,值为给定表达式结果的对象

1
2
3
4
5
6
const mapObject = (arr, fn) => 
(a => (a = [arr, arr.map(fn)], a[0].reduce( (acc,val,ind) => (acc[val] = a[1][ind], acc), {}) )) ( );
/*
const squareIt = arr => mapObject(arr, a => a*a)
squareIt([1,2,3]) // { 1: 1, 2: 4, 3: 9 }
*/

⬆ back to top

nthElement

返回数组的第n个对象.

使用 Array.slice() 获取满足给定条件的数组的第一个元素
如果给定的索引超出范围,返回 [].
参数 n 默认为第一个元素

1
2
3
const nthElement = (arr, n=0) => (n>0? arr.slice(n,n+1) : arr.slice(n))[0];
// nthElement(['a','b','c'],1) -> 'b'
// nthElement(['a','b','b'],-3) -> 'a'

⬆ back to top

pick

返回对象的一个拷贝,返回的对象只含有给定的键的键值对

1
2
3
const pick = (obj, arr) =>
arr.reduce((acc, curr) => (curr in obj && (acc[curr] = obj[curr]), acc), {});
// pick({ 'a': 1, 'b': '2', 'c': 3 }, ['a', 'c']) -> { 'a': 1, 'c': 3 }

⬆ back to top

pull

抽取数组中指定的元素

使用 Array.filter()Array.includes() 抽出不需要的元素.
使用 Array.length = 0 重置数组并且使用 Array.push() 重新填充抽取后的数组.

1
2
3
4
5
6
7
const pull = (arr, ...args) => {
let pulled = arr.filter((v, i) => !args.includes(v));
arr.length = 0; pulled.forEach(v => arr.push(v));
};
// let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
// pull(myArray, 'a', 'c');
// console.log(myArray) -> [ 'b', 'b' ]

⬆ back to top

remove

移除数组中给定表达式为 false. 的值

使用 Array.filter() 找到表达式为 true 的值,然后通过 Array.reduce() 使用 Array.splice() 移除.

1
2
3
4
5
6
const remove = (arr, func) =>
Array.isArray(arr) ? arr.filter(func).reduce((acc, val) => {
arr.splice(arr.indexOf(val), 1); return acc.concat(val);
}, [])
: [];
// remove([1, 2, 3, 4], n => n % 2 == 0) -> [2, 4]

⬆ back to top

sample

返回数组的一个随机元素

使用 Math.random() 创建一个随机数,然后和 length 相乘之后通过 Math.floor() 找到一个最接近的数.

1
2
const sample = arr => arr[Math.floor(Math.random() * arr.length)];
// sample([3, 7, 9, 11]) -> 9

⬆ back to top

shuffle

打乱数组中值的顺序

使用 Array.sort() 重新排序, 使用 Math.random() - 0.5 作为compareFunction.

1
2
const shuffle = arr => arr.sort(() => Math.random() - 0.5);
// shuffle([1,2,3]) -> [2,3,1]

⬆ back to top

similarity

返回一个数组,它的值两个数组里面都存在.

使用 includes() 找出values不含有的元素,使用filter()移除.

1
2
const similarity = (arr, values) => arr.filter(v => values.includes(v));
// similarity([1,2,3], [1,2,4]) -> [1,2]

⬆ back to top

symmetricDifference

返回两个数组的对称差异.

通过两个数组分别创建 Set, 然后使用 Array.filter() 找出不在另外一个集合中的元素.

1
2
3
4
5
const symmetricDifference = (a, b) => {
const sA = new Set(a), sB = new Set(b);
return [...a.filter(x => !sB.has(x)), ...b.filter(x => !sA.has(x))];
}
// symmetricDifference([1,2,3], [1,2,4]) -> [3,4]

⬆ back to top

tail

返回数组中除去第一个元素的集合

如果数组length 大于 1, 返回 arr.slice(1) 否则就返回整个数组.

1
2
3
const tail = arr => arr.length > 1 ? arr.slice(1) : arr;
// tail([1,2,3]) -> [2,3]
// tail([1]) -> [1]

⬆ back to top

take

返回前n个元素.

1
2
3
const take = (arr, n = 1) => arr.slice(0, n);
// take([1, 2, 3], 5) -> [1, 2, 3]
// take([1, 2, 3], 0) -> []

⬆ back to top

takeRight

返回后n个元素.

1
2
3
const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length);
// takeRight([1, 2, 3], 2) -> [ 2, 3 ]
// takeRight([1, 2, 3]) -> [3]

⬆ back to top

union

合并两个集合(结果不含重复元素)

1
2
const union = (a, b) => Array.from(new Set([...a, ...b]));
// union([1,2,3], [4,3,2]) -> [1,2,3,4]

⬆ back to top

without

根据指定的值过滤数组

1
2
const without = (arr, ...args) => arr.filter(v => !args.includes(v));
// without([2, 1, 2, 3], 1, 2) -> [3]

⬆ back to top

zip

根据原始数组的位置把多个数组压缩

使用 Math.max.apply() 获取输入数组中最大的长度,根据这个长度使用Array.from()创建一个新的数组,之后把输入数组的映射压缩到里面,如果某个数组缺少元素使用undefined代替

1
2
3
4
5
6
7
8
const zip = (...arrays) => {
const maxLength = Math.max(...arrays.map(x => x.length));
return Array.from({length: maxLength}).map((_, i) => {
return Array.from({length: arrays.length}, (_, k) => arrays[k][i]);
})
}
//zip(['a', 'b'], [1, 2], [true, false]); -> [['a', 1, true], ['b', 2, false]]
//zip(['a'], [1, 2], [true, false]); -> [['a', 1, true], [undefined, 2, false]]

⬆ back to top

Browser

bottomVisible

如果到达页面底部,返回true否则返回false

使用 scrollY, scrollHeightclientHeight 判断是否到达页面底部

1
2
3
const bottomVisible = () =>
document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight;
// bottomVisible() -> true

⬆ back to top

currentURL

返回当前页面的URL.

使用 window.location.href 获取当前页面URL.

1
2
const currentURL = () => window.location.href;
// currentUrl() -> 'https://google.com'

⬆ back to top

elementIsVisibleInViewport

如果一个元素在视口可见,返回true否则返回false

使用 Element.getBoundingClientRect()window.inner(Width|Height) 判断元素是否在视口可见,第二个参数设置为true表示是否部分可见,默认值为false

1
2
3
4
5
6
7
8
9
10
const elementIsVisibleInViewport = (el, partiallyVisible = false) => {
const { top, left, bottom, right } = el.getBoundingClientRect();
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;
};
// 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)

⬆ back to top

getScrollPosition

返回滚动条在当前页面的位置.

如果 pageXOffsetpageYOffset 未定义,使用 scrollLeft and scrollTop.

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

⬆ back to top

getURLParameters

返回URL查询字符串对象.

1
2
3
4
5
const getURLParameters = url =>
url.match(/([^?=&]+)(=([^&]*))/g).reduce(
(a, v) => (a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1), a), {}
);
// getURLParameters('http://url.com/page?name=Adam&surname=Smith') -> {name: 'Adam', surname: 'Smith'}

⬆ back to top

redirect

重定向到指定的URL.

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

⬆ back to top

scrollToTop

平滑滚动到页面顶部.

1
2
3
4
5
6
7
8
const scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop;
if (c > 0) {
window.requestAnimationFrame(scrollToTop);
window.scrollTo(0, c - c / 8);
}
};
// scrollToTop()

⬆ back to top

Date

getDaysDiffBetweenDates

返回两个Date对象的天数差

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

⬆ back to top

JSONToDate

转换一个JSON对象为时间.

1
2
3
4
5
const JSONToDate = arr => {
const dt = new Date(parseInt(arr.toString().substr(6)));
return `${ dt.getDate() }/${ dt.getMonth() + 1 }/${ dt.getFullYear() }`
};
// JSONToDate(/Date(1489525200000)/) -> "14/3/2017"

⬆ back to top

toEnglishDate

把美国时间转换为英国时间.

1
2
3
const toEnglishDate  = (time) =>
{try{return new Date(time).toISOString().split('T')[0].replace(/-/g, '/')}catch(e){return}};
// toEnglishDate('09/21/2010') -> '21/09/2010'

⬆ back to top

Function

chainAsync

串联异步方法.

1
2
3
4
5
6
7
8
const chainAsync = fns => { let curr = 0; const next = () => fns[curr++](next); next(); };
/*
chainAsync([
next => { console.log('0 seconds'); setTimeout(next, 1000); },
next => { console.log('1 second'); setTimeout(next, 1000); },
next => { console.log('2 seconds'); }
])
*/

⬆ back to top

compose

从右往左执行函数组合

1
2
3
4
5
6
7
const compose = (...fns) => fns.reduce((f, g) => (...args) => f(g(...args)));
/*
const add5 = x => x + 5
const multiply = (x, y) => x * y
const multiplyAndAdd5 = compose(add5, multiply)
multiplyAndAdd5(5, 2) -> 15
*/

⬆ back to top

curry

对函数进行柯里化

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

⬆ back to top

functionName

打印函数名称

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

⬆ back to top

pipe

从左往右执行函数组合

1
2
3
4
5
6
7
const pipeFunctions = (...fns) => fns.reduce((f, g) => (...args) => g(f(...args)));
/*
const add5 = x => x + 5
const multiply = (x, y) => x * y
const multiplyAndAdd5 = pipeFunctions(multiply, add5)
multiplyAndAdd5(5, 2) -> 15
*/

⬆ back to top

promisify

把异步函数转化为promise

In Node 8+, you can use util.promisify

1
2
3
4
5
6
7
8
const promisify = func =>
(...args) =>
new Promise((resolve, reject) =>
func(...args, (err, result) =>
err ? reject(err) : resolve(result))
);
// const delay = promisify((d, cb) => setTimeout(cb, d))
// delay(2000).then(() => console.log('Hi!')) -> Promise resolves after 2s

⬆ back to top

runPromisesInSeries

执行一系列promise函数

1
2
3
const runPromisesInSeries = ps => ps.reduce((p, next) => p.then(next), Promise.resolve());
// 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

⬆ back to top

sleep

延迟执行异步函数

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

1
2
3
4
5
6
7
8
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
/*
async function sleepyWork() {
console.log('I\'m going to sleep for 1 second.');
await sleep(1000);
console.log('I woke up after 1 second.');
}
*/

⬆ back to top

Math

arrayAverage

返回数组的平均值

1
2
const arrayAverage = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length;
// arrayAverage([1,2,3]) -> 2

⬆ back to top

arraySum

返回数组的和

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

⬆ back to top

collatz

实现Collatz算法.

如果 n 是偶数, 返回 n/2. 否则返回 3n+1.

1
2
3
const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1);
// collatz(8) --> 4
// collatz(5) --> 16

⬆ back to top

digitize

把数字转为数组

1
2
const digitize = n => [...''+n].map(i => parseInt(i));
// digitize(2334) -> [2, 3, 3, 4]

⬆ back to top

distance

返回两点距离.

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

⬆ back to top

factorial

计算一个数字的阶乘.

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

⬆ back to top

fibonacci

指定一个长度,输出斐波那契数列

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

⬆ back to top

gcd

计算两个数字之间的最大公约数。

1
2
const gcd = (x, y) => !y ? x : gcd(y, x % y);
// gcd (8, 36) -> 4

⬆ back to top

hammingDistance

计算两个值的Hamming距离.

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

⬆ back to top

isDivisible

检查第一个数字是否可被第二个数字整除.

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

⬆ back to top

isEven

检查数字是否为偶数

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

⬆ back to top

lcm

计算两个数字的最小公倍数.

1
2
3
4
5
const lcm = (x,y) => {
const gcd = (x, y) => !y ? x : gcd(y, x % y);
return Math.abs(x*y)/(gcd(x,y));
};
// lcm(12,7) -> 84

⬆ back to top

median

返回数组的中位数

1
2
3
4
5
6
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;
};
// median([5,6,50,1,-5]) -> 5
// median([0,10,-2,7]) -> 3.5

⬆ back to top

palindrome

判断给定字符串是否是回文字符串(回文字符串是正读和反读都一样的字符串,比如“level”或者“noon”)

1
2
3
4
5
const palindrome = str => {
const s = str.toLowerCase().replace(/[\W_]/g,'');
return s === s.split('').reverse().join('');
}
// palindrome('taco cat') -> true

⬆ back to top

percentile

使用百分位数公式来计算给定数组中有多少数字小于或等于给定值。

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

⬆ back to top

powerset

输出给定数组的所有子集

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

⬆ back to top

randomIntegerInRange

返回指定范围内的随机整数

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

⬆ back to top

randomNumberInRange

返回指定范围内的随机数

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

⬆ back to top

round

将数字四舍五入到指定的数字位数.

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

⬆ back to top

standardDeviation

返回数组的标准差

1
2
3
4
5
6
7
8
9
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(Math.pow(val - mean, 2)), [])
.reduce((acc, val) => acc + val, 0) / (arr.length - (usePopulation ? 0 : 1))
);
};
// standardDeviation([10,2,38,23,38,23,21]) -> 13.284434142114991 (sample)
// standardDeviation([10,2,38,23,38,23,21], true) -> 12.29899614287479 (population)

⬆ back to top

Media

speechSynthesis

语音合成 (实验特性).

详情查看 SpeechSynthesisUtterance interface of the Web Speech API.

1
2
3
4
5
6
const speechSynthesis = message => {
const msg = new SpeechSynthesisUtterance(message);
msg.voice = window.speechSynthesis.getVoices()[0];
window.speechSynthesis.speak(msg);
};
// speechSynthesis('Hello, World') -> plays the message

⬆ back to top

Node

JSONToFile

将一个JSON对象转换为文件.

1
2
3
const fs = require('fs');
const JSONToFile = (obj, filename) => fs.writeFile(`${filename}.json`, JSON.stringify(obj, null, 2))
// JSONToFile({test: "is passed"}, 'testJsonFile') -> writes the object to 'testJsonFile.json'

⬆ back to top

readFileLines

读取指定的文件并且根据行生成数组

1
2
3
4
5
6
7
8
9
10
11
const fs = require('fs');
const readFileLines = filename => fs.readFileSync(filename).toString('UTF8').split('\n');
/*
contents of test.txt :
line1
line2
line3
___________________________
let arr = readFileLines('test.txt')
console.log(arr) // -> ['line1', 'line2', 'line3']
*/

⬆ back to top

Object

cleanObj

移除对象中除去给定的属性名之外的属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
const cleanObj = (obj, keysToKeep = [], childIndicator) => {
Object.keys(obj).forEach(key => {
if (key === childIndicator) {
cleanObj(obj[key], keysToKeep, childIndicator);
} else if (!keysToKeep.includes(key)) {
delete obj[key];
}
})
}
/*
const testObj = {a: 1, b: 2, children: {a: 1, b: 2}}
cleanObj(testObj, ["a"],"children")
console.log(testObj)// { a: 1, children : { a: 1}}
*/

⬆ back to top

objectFromPairs

根据给定的键值对生成对象

1
2
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {});
// objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2}

⬆ back to top

objectToPairs

转换一个对象为数组

1
2
const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]);
// objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]])

⬆ back to top

shallowClone

创建一个对象的浅拷贝.

1
2
3
4
5
6
const shallowClone = obj => Object.assign({}, obj);
/*
const a = { x: true, y: 1 };
const b = shallowClone(a);
a === b -> false
*/

⬆ back to top

truthCheckCollection

检查某个属性名是否在一个数组中都存在

1
2
truthCheckCollection = (collection, pre) => (collection.every(obj => obj[pre]));
// truthCheckCollection([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}], "sex") -> true

⬆ back to top

String

anagrams

生成一个字符串的所有字符排列组合(包含重复)

1
2
3
4
5
6
const anagrams = str => {
if (str.length <= 2) return str.length === 2 ? [str, str[1] + str[0]] : [str];
return str.split('').reduce((acc, letter, i) =>
acc.concat(anagrams(str.slice(0, i) + str.slice(i + 1)).map(val => letter + val)), []);
};
// anagrams('abc') -> ['abc','acb','bac','bca','cab','cba']

⬆ back to top

Capitalize

将给定字符串首字母大写.

1
2
3
4
const capitalize = ([first,...rest], lowerRest = false) =>
first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''));
// capitalize('myName') -> 'MyName'
// capitalize('myName', true) -> 'Myname'

⬆ back to top

capitalizeEveryWord

将给定字符串的每个单词首字母大写.

1
2
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase());
// capitalizeEveryWord('hello world!') -> 'Hello World!'

⬆ back to top

escapeRegExp

转义字符串以便在正则表达式中使用

1
2
const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
// escapeRegExp('(test)') -> \\(test\\)

⬆ back to top

fromCamelCase

把camelcase字符串转换成其他格式

1
2
3
4
5
6
const fromCamelCase = (str, separator = '_') =>
str.replace(/([a-z\d])([A-Z])/g, '$1' + separator + '$2')
.replace(/([A-Z]+)([A-Z][a-z\d]+)/g, '$1' + separator + '$2').toLowerCase();
// fromCamelCase('someDatabaseFieldName', ' ') -> 'some database field name'
// fromCamelCase('someLabelThatNeedsToBeCamelized', '-') -> 'some-label-that-needs-to-be-camelized'
// fromCamelCase('someJavascriptProperty', '_') -> 'some_javascript_property'

⬆ back to top

reverseString

反转字符串

1
2
const reverseString = str => [...str].reverse().join('');
// reverseString('foobar') -> 'raboof'

⬆ back to top

sortCharactersInString

按照字母顺序重新排列字符串

1
2
3
const sortCharactersInString = str =>
str.split('').sort((a, b) => a.localeCompare(b)).join('');
// sortCharactersInString('cabbage') -> 'aabbceg'

⬆ back to top

toCamelCase

把一个字符串转换为camelcase.

1
2
3
4
5
6
const toCamelCase = str =>
str.replace(/^([A-Z])|[\s-_]+(\w)/g, (match, p1, p2, offset) => p2 ? p2.toUpperCase() : p1.toLowerCase());
// toCamelCase("some_database_field_name") -> 'someDatabaseFieldName'
// toCamelCase("Some label that needs to be camelized") -> 'someLabelThatNeedsToBeCamelized'
// toCamelCase("some-javascript-property") -> 'someJavascriptProperty'
// toCamelCase("some-mixed_string with spaces_underscores-and-hyphens") -> 'someMixedStringWithSpacesUnderscoresAndHyphens'

⬆ back to top

truncateString

根据指定长度截取字符串

1
2
3
const truncateString = (str, num) =>
str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str;
// truncateString('boomerang', 7) -> 'boom...'

⬆ back to top

Utility

coalesce

返回第一个不为null/undefined的参数

1
2
const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_))
// coalesce(null,undefined,"",NaN, "Waldo") -> ""

⬆ back to top

coalesceFactory

实现自定义coalesce函数

1
2
3
const coalesceFactory = valid => (...args) => args.find(valid);
// const customCoalesce = coalesceFactory(_ => ![null, undefined, "", NaN].includes(_))
// customCoalesce(undefined, null, NaN, "", "Waldo") //-> "Waldo"

⬆ back to top

extendHex

将3位数的颜色代码扩展为6位数的颜色代码

1
2
3
4
const extendHex = shortHex =>
'#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join('')
// extendHex('#03f') -> '#0033ff'
// extendHex('05a') -> '#0055aa'

⬆ back to top

getType

获取一个值的原生类型.

1
2
3
const getType = v =>
v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase();
// getType(new Set([1,2,3])) -> "set"

⬆ back to top

hexToRGB

将hex色值转换为RGB

1
2
3
4
5
6
7
8
const hexToRgb = hex => {
const extendHex = shortHex =>
'#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join('');
const extendedHex = hex.slice(hex.startsWith('#') ? 1 : 0).length === 3 ? extendHex(hex) : hex;
return `rgb(${parseInt(extendedHex.slice(1), 16) >> 16}, ${(parseInt(extendedHex.slice(1), 16) & 0x00ff00) >> 8}, ${parseInt(extendedHex.slice(1), 16) & 0x0000ff})`;
}
// hexToRgb('#27ae60') -> 'rgb(39, 174, 96)'
// hexToRgb('#acd') -> 'rgb(170, 204, 221)'

⬆ back to top

isArray

检查给定对象是否是数组

1
2
3
const isArray = val => !!val && Array.isArray(val);
// isArray(null) -> false
// isArray([1]) -> true

⬆ back to top

isBoolean

检查给定对象是否是布尔值

1
2
3
const isBoolean = val => typeof val === 'boolean';
// isBoolean(null) -> false
// isBoolean(false) -> true

⬆ back to top

isFunction

检查给定对象是否是方法

1
2
3
const isFunction = val => val && typeof val === 'function';
// isFunction('x') -> false
// isFunction(x => x) -> true

⬆ back to top

isNumber

检查给定对象是否是数字

1
2
3
const isNumber = val => typeof val === 'number';
// isNumber('1') -> false
// isNumber(1) -> true

⬆ back to top

isString

检查给定对象是否是字符串

1
2
3
const isString = val => typeof val === 'string';
// isString(10) -> false
// isString('10') -> true

⬆ back to top

isSymbol

检查给定对象是否是symbol.

1
2
3
const isSymbol = val => typeof val === 'symbol';
// isSymbol('x') -> false
// isSymbol(Symbol('x')) -> true

⬆ back to top

RGBToHex

将RGB色值转换为Hex

1
2
const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0');
// RGBToHex(255, 165, 1) -> 'ffa501'

⬆ back to top

timeTaken

计算函数执行时间

1
2
3
4
5
6
const timeTaken = callback => {
console.time('timeTaken'); const r = callback();
console.timeEnd('timeTaken'); return r;
};
// timeTaken(() => Math.pow(2, 10)) -> 1024
// (logged): timeTaken: 0.02099609375ms

⬆ back to top

toOrdinalSuffix

Adds an ordinal suffix to a number.

Use the modulo operator (%) to find values of single and tens digits.
Find which ordinal pattern digits match.
If digit is found in teens pattern, use teens ordinal.

1
2
3
4
5
6
7
const toOrdinalSuffix = num => {
const int = parseInt(num), digits = [(int % 10), (int % 100)],
ordinals = ['st', 'nd', 'rd', 'th'], oPattern = [1, 2, 3, 4],
tPattern = [11, 12, 13, 14, 15, 16, 17, 18, 19];
return oPattern.includes(digits[0]) && !tPattern.includes(digits[1]) ? int + ordinals[digits[0] - 1] : int + ordinals[3];
};
// toOrdinalSuffix("123") -> "123rd"

⬆ back to top

UUIDGenerator

生成UUID.

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

⬆ back to top

validateEmail

验证是否为邮箱

1
2
3
const validateEmail = str =>
/^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(str);
// validateEmail(mymail@gmail.com) -> true

⬆ back to top

validateNumber

验证是否为数字

1
2
const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n;
// validateNumber('10') -> true

⬆ back to top

Credits

Icons made by Smashicons from www.flaticon.com is licensed by CC 3.0 BY.