項目地址: https://github.com/dragonir/U...
Util.js 是對經常使用函數的封裝,方便在實際項目中使用,主要內容包含:數組類、瀏覽器類、日期類、函數類、數學類、媒體類、節點類、對象類、字符串類、類型檢測類、正則表達式類等內容。
<script type="javascript/text" src="./browser.js"></script>
或引入壓縮版javascript
<script type="javascript/text" src="./browser.min.js"></script>
<script type="javascript/text" src="./Util.js"></script>
或引入壓縮版html
<script type="javascript/text" src="./Util.min.js"></script>
_Example 1_: 經過調用 isArray() 方法來判斷數值是否爲數組java
var arr = []; var obj = {}; console.log(Util.isArray(arr)); // true console.log(Util.isArray(obj)); // false
_Example 2_: 經過調用 extendHex() 方法將3位色值轉換爲6位色值git
console.log(Util.extendHex("#03f")); // #0033ff console.log(Util.extendHex("05a")); // #0055aa console.log(Util.extendHex("#03c03c")); // #03c03c
文件名 | 描述 |
---|---|
Util.js | 工具函數主文件 |
Util.min.js | 工具函數壓縮版 |
RegExp.js | 正則表達式封裝 |
RegExp.min.js | 正則表達式封裝壓縮版 |
browser.js | ES6向後兼容 |
browser.min.js | ES6向後兼容 |
string-utils.js | 字符串工具函數(待整合) |
00. 經常使用正則表達式示例-RegExp.html | 正則表達式測試演示 |
01. 經常使用工具函數示例-Util-數組類.html | 數組類測試演示 |
02. 經常使用工具函數示例-Util-瀏覽器類.html | 瀏覽器類測試演示 |
03. 經常使用工具函數示例-Util-日期類.html | 日期類測試演示 |
04. 經常使用工具函數示例-Util-函數類.html | 函數類測試演示 |
05. 經常使用工具函數示例-Util-數學類.html | 數學類測試演示 |
06. 經常使用工具函數示例-Util-媒體類.html | 媒體類測試演示 |
07. 經常使用工具函數示例-Util-節點類.html | 設爲首頁 |
08. 經常使用工具函數示例-Util-對象類.html | 對象類測試演示 |
09. 經常使用工具函數示例-Util-字符串.html | 字符串測試演示 |
10. 經常使用工具函數示例-Util-其餘實用函數.html | 其餘實用函數測試演示 |
11. 經常使用工具函數示例-Util-類型檢測.html | 類型檢測 |
README.MD | 項目描述文件 |
logo.png | 項目圖標 |
感謝原做者分享了大量有用的Javascript片斷,我在其基礎上將其封裝爲一個文件方便使用。github
源項目: https://github.com/Chalarangelo/30-seconds-of-code
如下是項目具體內容以及詳細註釋,可經過查詢找到本身須要的函數。
arrayMax
arrayMin
chunk
compact
countOccurrences
deepFlatten
difference
distinctValuesOfArray
dropElements
everyNth
filterNonUnique
flatten
flattenDepth
groupBy
head
initial
initializeArrayWithRange
initializeArrayWithValues
intersection
last
mapObject
nthElement
pick
pull
remove
sample
shuffle
similarity
symmetricDifference
tail
take
takeRight
union
without
zip
bottomVisible
currentURL
elementIsVisibleInViewport
getScrollPosition
getURLParameters
redirect
scrollToTop
arrayAverage
arraySum
collatz
digitize
distance
factorial
fibonacci
gcd
hammingDistance
isDivisible
isEven
lcm
median
palindrome
percentile
powerset
randomIntegerInRange
randomNumberInRange
round
standardDeviation
anagrams
capitalize
capitalizeEveryWord
escapeRegExp
fromCamelCase
reverseString
sortCharactersInString
toCamelCase
truncateString
coalesce
coalesceFactory
extendHex
getType
hexToRGB
isArray
isBoolean
isFunction
isNumber
isString
isSymbol
RGBToHex
timeTaken
toOrdinalSuffix
UUIDGenerator
validateEmail
validateNumber
⬆ 返回頂部算法
返回數組中的最大值。json
將Math.max()
與擴展運算符 (...
) 結合使用以獲取數組中的最大值。api
const arrayMax = arr => Math.max(...arr); // arrayMax([10, 1, 5]) -> 10
⬆ 返回頂部數組
返回數組中的最小值。
將Math.min()
與擴展運算符 (...
) 結合使用以獲取數組中的最小值。
const arrayMin = arr => Math.min(...arr); // arrayMin([10, 1, 5]) -> 1
將數組塊劃分爲指定大小的較小數組。
使用Array.from()
建立新的數組, 這符合將生成的區塊數。使用Array.slice()
將新數組的每一個元素映射到size
長度的區塊。若是原始數組不能均勻拆分, 則最終的塊將包含剩餘的元素。
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]]
從數組中移除 falsey 值。
使用Array.filter()
篩選出 falsey 值 (false
、null
、0
、""
、undefined
和NaN
).
const compact = (arr) => arr.filter(Boolean); // compact([0, 1, false, 2, '', 3, 'a', 'e'*23, NaN, 's', 34]) -> [ 1, 2, 3, 'a', 's', 34 ]
計算數組中值的出現次數。
使用Array.reduce()
在每次遇到數組中的特定值時遞增計數器。
const countOccurrences = (arr, value) => arr.reduce((a, v) => v === value ? a + 1 : a + 0, 0); // countOccurrences([1,1,2,1,2,3], 1) -> 3
深拼合數組。
使用遞歸。使用Array.concat()
與空數組 ([]
) 和跨頁運算符 (...
) 來拼合數組。遞歸拼合做爲數組的每一個元素。
const deepFlatten = arr => [].concat(...arr.map(v => Array.isArray(v) ? deepFlatten(v) : v)); // deepFlatten([1,[2],[[3],4],5]) -> [1,2,3,4,5]
返回兩個數組之間的差別。
從b
建立Set
, 而後使用Array.filter()
on 只保留a
b
中不包含的值.
const difference = (a, b) => { const s = new Set(b); return a.filter(x => !s.has(x)); }; // difference([1,2,3], [1,2,4]) -> [3]
返回數組的全部不一樣值。
使用 ES6 Set
和...rest
運算符放棄全部重複的值。
const distinctValuesOfArray = arr => [...new Set(arr)]; // distinctValuesOfArray([1,2,2,3,4,4,5]) -> [1,2,3,4,5]
移除數組中的元素, 直到傳遞的函數返回true
。返回數組中的其他元素。
在數組中循環, 使用Array.shift()
將數組的第一個元素除去, 直到函數的返回值爲true
。返回其他元素。
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]
返回數組中的每一個第 n 個元素。
使用Array.filter()
建立一個包含給定數組的每一個第 n 個元素的新數組。
const everyNth = (arr, nth) => arr.filter((e, i) => i % nth === 0); // everyNth([1,2,3,4,5,6], 2) -> [ 1, 3, 5 ]
篩選出數組中的非惟一值。
對於只包含惟一值的數組, 請使用Array.filter()
。
const filterNonUnique = arr => arr.filter(i => arr.indexOf(i) === arr.lastIndexOf(i)); // filterNonUnique([1,2,2,3,4,4,5]) -> [1,3,5]
拼合數組。
使用Array.reduce()
獲取數組中的全部元素和concat()
以拼合它們。
const flatten = arr => arr.reduce((a, v) => a.concat(v), []); // flatten([1,[2],3,4]) -> [1,2,3,4]
將數組向上拼合到指定深度。
使用遞歸, 遞減depth
, 每層深度爲1。使用Array.reduce()
和Array.concat()
來合併元素或數組。基本狀況下, 對於等於1
的depth
中止遞歸。省略第二個元素,depth
僅拼合到1
的深度 (單個拼合)。
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]
根據給定函數對數組元素進行分組。
使用Array.map()
將數組的值映射到函數或屬性名。使用Array.reduce()
建立一個對象, 其中的鍵是從映射的結果生成的。
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']}
返回列表的頭。
使用arr[0]
可返回傳遞的數組的第一個元素。
const head = arr => arr[0]; // head([1,2,3]) -> 1
返回除最後一個數組以外的全部元素。
使用 "arr.slice(0,-1)
" 返回數組的最後一個元素。
const initial = arr => arr.slice(0, -1); // initial([1,2,3]) -> [1,2]
初始化包含指定範圍內的數字的數組。
使用Array(end-start)
建立所需長度的數組Array.map()
以填充區域中所需的值。能夠省略start
以使用默認值0
.
const initializeArrayWithRange = (end, start = 0) => Array.from({ length: end - start }).map((v, i) => i + start); // initializeArrayWithRange(5) -> [0,1,2,3,4]
初始化並填充具備指定值的數組。
使用Array(n)
建立所需長度的數組,fill(v)
以填充所需的值。能夠省略value
以使用默認值0
.
const initializeArrayWithValues = (n, value = 0) => Array(n).fill(value); // initializeArrayWithValues(5, 2) -> [2,2,2,2,2]
返回兩個數組中存在的元素的列表。
從b
建立Set
, 而後使用Array.filter()
on a
只保留b
中包含的值.
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]
返回數組中的最後一個元素。
使用arr.length - 1
可計算給定數組的最後一個元素的索引並返回它。
const last = arr => arr[arr.length - 1]; // last([1,2,3]) -> 3
使用函數將數組的值映射到對象, 其中鍵值對由原始值做爲鍵和映射值組成。
使用匿名內部函數範圍來聲明未定義的內存空間, 使用閉包來存儲返回值。使用新的Array
可將該數組與函數的映射放在其數據集上, 而逗號運算符返回第二個步驟, 而不須要從一個上下文移動到另外一個環境 (因爲關閉和操做順序)。
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 } */
返回數組的第 n 個元素。
使用Array.slice()
可獲取包含第 n 個元素的數組。若是索引超出界限, 則返回[]
。省略第二個參數n
, 以獲取數組的第一個元素。
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'
從對象中選取對應於給定鍵的鍵值對。
使用Array.reduce()
將篩選/選取的密鑰轉換回具備相應鍵值對的對象 (若是在 obj 中存在該鍵)。
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 }
對原始數組進行變異, 以篩選出指定的值。
使用Array.filter()
和Array.includes()
來拉出不須要的值。使用Array.length = 0
可將傳入的數組中的長度重置爲零, 並將其設置爲Array.push()
, 以便僅使用所提取的值填充它。
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' ]
從數組中移除給定函數返回false
的元素.
使用Array.filter()
查找返回 truthy 值的數組元素和Array.reduce()
以使用Array.splice()
刪除元素。使用三參數 (func
value, index, array
調用函數).
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]
返回數組中的隨機元素。
使用Math.random()
生成一個隨機數, 將它與length
相乘, 並使用數學將其舍入到最接近的整數Math.floor()
。此方法也適用於字符串。
const sample = arr => arr[Math.floor(Math.random() * arr.length)]; // sample([3, 7, 9, 11]) -> 9
隨機數組值的順序。
使用Array.sort()
可在比較器中使用Math.random()
從新排序元素。
const shuffle = arr => arr.sort(() => Math.random() - 0.5); // shuffle([1,2,3]) -> [2,3,1]
返回兩個數組中都顯示的元素的數組。
使用filter()
可刪除不屬於values
的值, 使用includes()
肯定.
const similarity = (arr, values) => arr.filter(v => values.includes(v)); // similarity([1,2,3], [1,2,4]) -> [1,2]
返回兩個數組之間的對稱差。
從每一個數組建立一個Set
, 而後對它們中的每個都使用Array.filter()
, 以便只保留其餘值中不包含的數值。
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]
返回數組中的全部元素, 除第一個。
若是數組的length
大於1
, 則返回arr.slice(1)
, 不然返回整個數組。
const tail = arr => arr.length > 1 ? arr.slice(1) : arr; // tail([1,2,3]) -> [2,3] // tail([1]) -> [1]
返回一個數組, 其中 n 個元素從開始處移除。
使用Array.slice()
建立數組的切片, 其中包含從開始處取出的n
元素。
const take = (arr, n = 1) => arr.slice(0, n); // take([1, 2, 3], 5) -> [1, 2, 3] // take([1, 2, 3], 0) -> []
返回一個數組, 其中 n 個元素從末尾移除。
使用Array.slice()
建立數組的切片, 其中包含從末尾取出的n
元素。
const takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length); // takeRight([1, 2, 3], 2) -> [ 2, 3 ] // takeRight([1, 2, 3]) -> [3]
返回在兩個數組中的任意一箇中存在的每一個元素。
建立一個Set
, 其中包含a
和b
的全部值, 並將其轉換爲數組。
const union = (a, b) => Array.from(new Set([...a, ...b])); // union([1,2,3], [4,3,2]) -> [1,2,3,4]
篩選出數組中具備指定值之一的元素。
使用Array.filter()
建立不包括的數組 (使用!Array.includes()
) 全部給定值。
const without = (arr, ...args) => arr.filter(v => !args.includes(v)); // without([2, 1, 2, 3], 1, 2) -> [3]
建立基於原始數組中的位置分組的元素數組。
使用Math.max.apply()
獲取參數中最長的數組。建立一個以該長度爲返回值的數組, 並使用 map 函數建立一個分組元素的數組Array.from()
若是參數數組的長度不一樣, 則在未找到任何值的狀況下使用undefined
。
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]]
若是頁的底部可見, 則返回true
, 不然爲false
。
使用scrollY
、scrollHeight
和clientHeight
來肯定頁面底部是否可見。
const bottomVisible = () => document.documentElement.clientHeight + window.scrollY >= document.documentElement.scrollHeight || document.documentElement.clientHeight; // bottomVisible() -> true
返回當前 URL。
使用window.location.href
獲取當前 URL。
const currentURL = () => window.location.href; // currentUrl() -> 'https://google.com'
若是指定的元素在視區中可見, 則返回true
, 不然爲false
。
使用Element.getBoundingClientRect()
和window.inner(Width|Height)
值以肯定給定元素在視區中是否可見。省略第二個參數以肯定該元素是否徹底可見, 或指定true
以肯定它是否部分可見。
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)
返回當前頁的滾動位置。
若是已定義, 則使用pageXOffset
和pageYOffset
, 不然scrollLeft
和scrollTop
。能夠省略el
以使用window
的默認值.
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}
返回一個包含當前 URL 參數的對象。
使用match()
與適當的正則表達式來獲取全部鍵值對,Array.reduce()
可將它們映射併合併到單個對象中。將location.search
做爲要應用於當前url
的參數傳遞.
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'}
重定向到指定的 URL。
使用window.location.href
或window.location.replace()
重定向到url
。傳遞第二個參數以模擬連接單擊 (true
-默認值) 或 HTTP 重定向 (false
).
const redirect = (url, asLink = true) => asLink ? window.location.href = url : window.location.replace(url); // redirect('https://google.com')
平滑滾動到頁面頂部。
使用document.documentElement.scrollTop
或document.body.scrollTop
從頂部獲取距離。從頂部的距離的一小部分滾動。使用window.requestAnimationFrame()
對滾動進行動畫處理。
const scrollToTop = () => { const c = document.documentElement.scrollTop || document.body.scrollTop; if (c > 0) { window.requestAnimationFrame(scrollToTop); window.scrollTo(0, c - c / 8); } }; // scrollToTop()
返回兩個日期之間的差別 (以天爲值)。
計算Date
對象之間的差別 (以天爲)。
const getDaysDiffBetweenDates = (dateInitial, dateFinal) => (dateFinal - dateInitial) / (1000 * 3600 * 24); // getDaysDiffBetweenDates(new Date("2017-12-13"), new Date("2017-12-22")) -> 9
將 JSON 對象轉換爲日期。
使用Date()
, 將 JSON 格式的日期轉換爲可讀格式 (dd/mm/yyyy
日)).
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"
將日期從美國格式轉換爲英文格式。
使用Date.toISOString()
、split('T')
和replace()
將日期從美式格式轉換爲英文格式。若是傳遞的時間不能轉換爲日期, 則拋出錯誤。
const toEnglishDate = (time) => {try{return new Date(time).toISOString().split('T')[0].replace(/-/g, '/')}catch(e){return}}; // toEnglishDate('09/21/2010') -> '21/09/2010'
鏈異步函數。
循環遍歷包含異步事件的函數數組, 當每一個異步事件完成時調用next
。
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'); } ]) */
執行從右向左的函數組合。
使用Array.reduce()
執行從右向左的函數組合。最後一個 (最右邊) 的函數能夠接受一個或多個參數;其他的函數必須是一元的。
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 */
Curries a function.
使用遞歸。若是提供的參數 (變量) 的數量足夠, 請調用傳遞的函數args
f
。不然, 返回須要其他參數的擴充函數f
。若是你想咖喱一個函數, 接受可變數目的參數 (如Math.min()
), 能夠選擇將參數的個數傳遞到第二個參數arity
(可變函數).
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
記錄函數的名稱。
使用console.debug()
和傳遞的方法的name
屬性將方法的名稱記錄到控制檯的debug
通道中。
const functionName = fn => (console.debug(fn.name), fn); // functionName(Math.max) -> max (logged in debug channel of console)
執行從左向右的函數組合。
使用Array.reduce()
與擴展運算符 (...
) 執行從左向右的函數組合。第一個 (最左邊的) 函數能夠接受一個或多個參數;其他的函數必須是一元的。
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 */
轉換異步函數以返回一個承諾。
使用討好返回一個返回調用原始函數的Promise
的函數。使用...rest
運算符傳入全部參數。
在節點 8 + 中, 可使用 util.promisify
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
運行一系列的承諾系列。
使用Array.reduce()
建立一個承諾鏈, 每一個承諾在解決時返回下一個承諾。
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
延遲異步函數的執行。
延遲執行async
函數的一部分, 將其放入休眠狀態, 返回Promise
.
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.'); } */
返回數字數組的平均值。
使用Array.reduce()
將每一個值添加到累加器中, 並以0
的值初始化, 除以數組的length
。
const arrayAverage = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length; // arrayAverage([1,2,3]) -> 2
返回一個數字數組的總和。
使用Array.reduce()
將每一個值添加到累加器中, 並以0
值初始化.
const arraySum = arr => arr.reduce((acc, val) => acc + val, 0); // arraySum([1,2,3,4]) -> 10
應用 Collatz 算法。
若是n
是偶數, 則返回n/2
。不然返回3n+1
.
const collatz = n => (n % 2 == 0) ? (n / 2) : (3 * n + 1); // collatz(8) --> 4 // collatz(5) --> 16
將數字轉換爲數字數組。
將數字轉換爲字符串, 在 ES6 ([...string]
) 中使用擴展運算符生成數組。使用Array.map()
和parseInt()
將每一個值轉換爲整數。
const digitize = n => [...''+n].map(i => parseInt(i)); // digitize(2334) -> [2, 3, 3, 4]
返回兩點之間的距離。
使用Math.hypot()
計算兩個點之間的歐氏距離。
const distance = (x0, y0, x1, y1) => Math.hypot(x1 - x0, y1 - y0); // distance(1,1, 2,3) -> 2.23606797749979
計算數字的階乘。
使用遞歸。若是n
小於或等於1
, 則返回1
。不然, 返回n
的乘積和n - 1
的階乘。若是n
爲負數, 則引起異常。
const factorial = n => n < 0 ? (() => { throw new TypeError('Negative numbers are not allowed!') })() : n <= 1 ? 1 : n * factorial(n - 1); // factorial(6) -> 720
生成一個數組, 包含斐波那契數列, 直到第 n 個項。
建立一個指定長度的空數組, 初始化前兩個值 (0
和1
)。使用Array.reduce()
可將值添加到數組中, 方法是使用前兩個值的總和, 但前兩個數值除外。
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]
計算兩個數字之間最大的公共除數。
使用遞歸。基本狀況是當y
等於0
時。在這種狀況下, 返回x
。不然, 返回y
的 GCD 和除法的其他部分x/y
.
const gcd = (x, y) => !y ? x : gcd(y, x % y); // gcd (8, 36) -> 4
計算兩個值之間的漢明距離。
使用 XOR 運算符 (^
) 可查找兩個數字之間的位差, 使用toString(2)
轉換爲二進制字符串。使用match(/1/g)
計算並返回字符串中1
的數目。.
const hammingDistance = (num1, num2) => ((num1 ^ num2).toString(2).match(/1/g) || '').length; // hammingDistance(2,3) -> 1
檢查第一個數值參數是否可被另外一個數字變量整除。
使用模數運算符 (%
) 檢查餘數是否等於0
.
const isDivisible = (dividend, divisor) => dividend % divisor === 0; // isDivisible(6,3) -> true
若是給定的數字爲偶數, 則返回true
, 不然爲false
。
檢查一個數字是奇數仍是使用模數 (%
) 運算符。若是數字爲偶數, 則返回true
, 若是數字爲奇數, 則爲false
。
const isEven = num => num % 2 === 0; // isEven(3) -> false
返回兩個數字中最不常見的倍數。
使用最大的公共除數 (GCD) 公式和Math.abs()
來肯定最不常見的倍數。GCD 公式使用遞歸。
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
返回數字數組的中間值。
找到數組的中間, 使用Array.sort()
來對值進行排序。若是length
爲奇數, 則返回中點的數字, 不然爲兩個中間數的平均值。
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
若是給定字符串爲迴文, 則返回true
, 不然爲false
。
轉換字符串toLowerCase()
並使用replace()
從其中刪除非字母數字字符。而後,split('')
到各個字符,reverse()
,join('')
, 並將其與原始的、不可逆轉的字符串進行比較, 而後將其轉換爲tolowerCase()
.
const palindrome = str => { const s = str.toLowerCase().replace(/[\W_]/g,''); return s === s.split('').reverse().join(''); } // palindrome('taco cat') -> true
使用百分比公式計算給定數組中有多少個數小於或等於給定值。
使用Array.reduce()
計算值的下面有多少, 有多少個數是相同的值, 並應用百分比公式。
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
返回給定數組的真子集。
使用Array.reduce()
與Array.map()
組合, 以循環訪問元素並將其合併到包含全部組合的數組中。
const powerset = arr => arr.reduce((a, v) => a.concat(a.map(r => [v].concat(r))), [[]]); // powerset([1,2]) -> [[], [1], [2], [2,1]]
返回指定範圍內的隨機整數。
使用Math.random()
生成一個隨機數並將其映射到所需的範圍, 使用Math.floor()
使其成爲整數。
const randomIntegerInRange = (min, max) => Math.floor(Math.random() * (max - min + 1)) + min; // randomIntegerInRange(0, 5) -> 2
返回指定範圍內的隨機數。
使用Math.random()
生成隨機值, 並使用乘法將其映射到所需的範圍。
const randomNumberInRange = (min, max) => Math.random() * (max - min) + min; // randomNumberInRange(2,10) -> 6.0211363285087005
將數字四捨五入到指定的位數。
使用Math.round()
和模板文本將數字舍入到指定的位數。省略第二個參數,decimals
舍入爲整數。
const round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`); // round(1.005, 2) -> 1.01
返回數字數組的標準誤差。
使用Array.reduce()
計算值的平均值、方差和方差的總和, 值的方差, 而後肯定標準誤差。能夠省略第二個參數以獲取樣本標準誤差, 或將其設置爲true
以獲取整體標準誤差。
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)
執行語音合成 (實驗)。
使用SpeechSynthesisUtterance.voice
和window.speechSynthesis.getVoices()
將郵件轉換爲語音。使用window.speechSynthesis.speak()
播放該消息。瞭解有關Web 語音 API 的 SpeechSynthesisUtterance 接口的詳細信息.
const speechSynthesis = message => { const msg = new SpeechSynthesisUtterance(message); msg.voice = window.speechSynthesis.getVoices()[0]; window.speechSynthesis.speak(msg); }; // speechSynthesis('Hello, World') -> plays the message
將 JSON 對象寫入文件。
使用fs.writeFile()
、模板文本和JSON.stringify()
將json
對象寫入.json
文件。
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'
返回指定文件中的行的數組。
在fs
節點包中使用readFileSync
函數能夠從文件建立Buffer
。使用toString(encoding)
函數將緩衝區轉換爲字符串。經過split
ing 文件內容行從文件內容建立數組 (每一個\n
).
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'] */
移除從 JSON 對象指定的屬性以外的任何特性。
使用Object.keys()
方法能夠遍歷給定的 json 對象並刪除在給定數組中不是include
d 的鍵。另外, 若是給它一個特殊的鍵 (childIndicator
), 它將在裏面深刻搜索, 並將函數應用於內部對象。
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}} */
從給定的鍵值對建立對象。
使用Array.reduce()
建立和組合鍵值對。
const objectFromPairs = arr => arr.reduce((a, v) => (a[v[0]] = v[1], a), {}); // objectFromPairs([['a',1],['b',2]]) -> {a: 1, b: 2}
從對象建立鍵值對數組的數組。
使用Object.keys()
和Array.map()
循環訪問對象的鍵並生成具備鍵值對的數組。
const objectToPairs = obj => Object.keys(obj).map(k => [k, obj[k]]); // objectToPairs({a: 1, b: 2}) -> [['a',1],['b',2]])
建立對象的淺表克隆。
使用Object.assign()
和一個空對象 ({}
) 建立原始的淺克隆。
const shallowClone = obj => Object.assign({}, obj); /* const a = { x: true, y: 1 }; const b = shallowClone(a); a === b -> false */
檢查謂詞 (第二個參數) 是否 truthy 集合的全部元素 (第一個參數)。
使用Array.every()
檢查每一個傳遞的對象是否具備指定的屬性, 以及是否返回 truthy 值。
truthCheckCollection = (collection, pre) => (collection.every(obj => obj[pre])); // truthCheckCollection([{"user": "Tinky-Winky", "sex": "male"}, {"user": "Dipsy", "sex": "male"}], "sex") -> true
生成字符串的全部字謎 (包含重複項)。
使用遞歸。對於給定字符串中的每一個字母, 爲其其他字母建立全部部分字謎。使用Array.map()
將字母與每一個部分變位詞組合在一塊兒, 而後將Array.reduce()
組合在一個數組中的全部字謎。基本狀況爲字符串length
等於2
或1
.
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']
將字符串的第一個字母大寫。
使用 destructuring 和toUpperCase()
可將第一個字母、...rest
用於獲取第一個字母以後的字符數組, 而後是Array.join('')
以使其成爲字符串。省略lowerRest
參數以保持字符串的其他部分不變, 或將其設置爲true
以轉換爲小寫。
const capitalize = ([first,...rest], lowerRest = false) => first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join('')); // capitalize('myName') -> 'MyName' // capitalize('myName', true) -> 'Myname'
將字符串中每一個單詞的首字母大寫。
使用replace()
匹配每一個單詞和toUpperCase()
的第一個字符以將其大寫。
const capitalizeEveryWord = str => str.replace(/\b[a-z]/g, char => char.toUpperCase()); // capitalizeEveryWord('hello world!') -> 'Hello World!'
轉義要在正則表達式中使用的字符串。
使用replace()
可轉義特殊字符。
const escapeRegExp = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // escapeRegExp('(test)') -> \\(test\\)
從匹配轉換字符串。
使用replace()
可刪除下劃線、連字符和空格, 並將單詞轉換爲匹配。省略第二個參數以使用默認分隔符_
.
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'
反轉字符串。
使用數組 destructuring 和Array.reverse()
可反轉字符串中字符的順序。使用join('')
組合字符以獲取字符串.
const reverseString = str => [...str].reverse().join(''); // reverseString('foobar') -> 'raboof'
按字母順序對字符串中的字符進行排序。
使用split('')
、Array.sort()
利用localeCompare()
從新組合使用join('')
.
const sortCharactersInString = str => str.split('').sort((a, b) => a.localeCompare(b)).join(''); // sortCharactersInString('cabbage') -> 'aabbceg'
將字符串轉換爲匹配。
使用replace()
可刪除下劃線、連字符和空格, 並將單詞轉換爲匹配。
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'
將字符串截斷爲指定長度。
肯定字符串的length
是否大於num
。將截斷的字符串返回到所需的長度, 並將...
追加到末尾或原始字符串。
const truncateString = (str, num) => str.length > num ? str.slice(0, num > 3 ? num - 3 : num) + '...' : str; // truncateString('boomerang', 7) -> 'boom...'
返回第一個非空/未定義參數。
使用Array.find()
返回第一個非null
/undefined
的參數。
const coalesce = (...args) => args.find(_ => ![undefined, null].includes(_)) // coalesce(null,undefined,"",NaN, "Waldo") -> ""
返回自定義的聯合函數, 返回從提供的參數驗證函數返回true
的第一個參數。
使用Array.find()
返回從提供的參數驗證函數返回true
的第一個參數。
const coalesceFactory = valid => (...args) => args.find(valid); // const customCoalesce = coalesceFactory(_ => ![null, undefined, "", NaN].includes(_)) // customCoalesce(undefined, null, NaN, "", "Waldo") //-> "Waldo"
將3位色碼擴展爲6位色碼。
使用Array.map()
、split()
和Array.join()
來加入映射數組, 將3位的 RGB notated 十六進制 color-code 轉換爲6位數字形式。Array.slice()
用於從字符串啓動中刪除#
, 由於它添加了一次。
const extendHex = shortHex => '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x+x).join('') // extendHex('#03f') -> '#0033ff' // extendHex('05a') -> '#0055aa'
返回值的本機類型。
若是值未定義或爲 null, 則返回小寫的構造函數名稱、"未定義" 或 "null"
const getType = v => v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase(); // getType(new Set([1,2,3])) -> "set"
將 colorcode 轉換爲rgb()
字符串。
使用按位右運算符和掩碼位與&
(and) 運算符將十六進制顏色代碼 (前綴爲#
) 轉換爲具備 RGB 值的字符串。若是它是一個3位數的 colorcode, 那麼用 extendHex () 函數 (ref.extendHex
代碼段) 擴展的6位 colorcode 進行相同的處理
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)'
檢查給定參數是否爲數組。
使用Array.isArray()
檢查某個值是否屬於數組。
const isArray = val => !!val && Array.isArray(val); // isArray(null) -> false // isArray([1]) -> true
檢查給定的參數是否爲本機布爾元素。
使用typeof
檢查某個值是否被歸類爲布爾基元。
const isBoolean = val => typeof val === 'boolean'; // isBoolean(null) -> false // isBoolean(false) -> true
檢查給定參數是否爲函數。
使用typeof
檢查某個值是否被歸類爲函數基元。
const isFunction = val => val && typeof val === 'function'; // isFunction('x') -> false // isFunction(x => x) -> true
檢查給定參數是否爲數字。
使用typeof
檢查某個值是否歸類爲數字基元。
const isNumber = val => typeof val === 'number'; // isNumber('1') -> false // isNumber(1) -> true
檢查給定參數是否爲字符串。
使用typeof
檢查某個值是否屬於字符串基元。
const isString = val => typeof val === 'string'; // isString(10) -> false // isString('10') -> true
檢查給定參數是否爲符號。
使用typeof
檢查某個值是否被歸類爲符號基元。
const isSymbol = val => typeof val === 'symbol'; // isSymbol('x') -> false // isSymbol(Symbol('x')) -> true
將 RGB 組件的值轉換爲 colorcode。
使用按位左移位運算符 (<<
) 和toString(16)
將給定的 RGB 參數轉換爲十六進制字符串, 而後padStart(6,'0')
以獲取6位十六進制值。
const RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0'); // RGBToHex(255, 165, 1) -> 'ffa501'
測量執行函數所用的時間。
使用console.time()
和console.timeEnd()
來測量開始和結束時間之間的差別, 以肯定回調執行所用的時間。
const timeTaken = callback => { console.time('timeTaken'); const r = callback(); console.timeEnd('timeTaken'); return r; }; // timeTaken(() => Math.pow(2, 10)) -> 1024 // (logged): timeTaken: 0.02099609375ms
將序號後綴添加到數字。
使用模數運算符 (%
) 查找單個和十位數字的值。查找匹配的序號模式數字。若是在青少年模式中發現數字, 請使用青少年序號。
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"
生成 UUID。
使用crypto
API 生成 UUID, 符合RFC4122版本4。
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'
若是給定的字符串是有效的電子郵件, 則返回true
, 不然爲false
。
使用正則表達式檢查電子郵件是否有效。若是電子郵件有效, 則返回 true, 若是沒有, 則返回false
。
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
若是給定值爲數字, 則返回true
, 不然爲false
。
將!isNaN
與parseFloat()
結合使用, 以檢查參數是否爲數字。使用isFinite()
檢查數字是不是有限的。使用Number()
檢查強制是否保持。
const validateNumber = n => !isNaN(parseFloat(n)) && isFinite(n) && Number(n) == n; // validateNumber('10') -> true