常用js片段组成的工具库,代码是es6编写,可以拿出单条片段进行babel再使用。
# npm
npm install viperjs
点击查看
arrayConcat
difference
includes
intersection
remove
sample
samplesize
chunk
compact
countoccurrences
deepFlatten
flatten
foreachright
distinctvaluesofarray
dropright
everynth
filternonunique
indexofall
initial
initializearraywithrange
initializearraywithvalues
issorted
join
last
longestitem
maxn
minn
nthelement
partition
pull
pullatindex
pullatvalue
reducedfilter
shuffle
similarity
symmetricdifference
tail
take
takeright
union
without
zip
zipobject
average
点击查看
点击查看
点击查看
数组拼接
viper.ArrayConcat = (arr, ...args) => [].concat(arr, ...args);
例子
viper.ArrayConcat([1], [1, 2, 3, [4]]) // [1, 2, 3, [4]]
数组比较 过滤出数组 a中数组b不包含的值
viper.difference = (a, b) => {
const s = new Set(b)
return a.filter(x => !s.has(x))
}
例子
viper.difference([1,2,3], [1,2])
// [3]
数组|字符串包含
viper.includes = (collection, val, formIdex=0) => collection.slice(formIdex).indexOf(val) != -1
例子
viper.includes("30-seconds-of-code", "code") // true
viper.includes([1, 2, 3, 4], [1, 2], 1) // false
数组交集 返回两数组中同时包含的值
viper.intersection = (a, b) => { const s = new Set(b); return a.filter(x => s.has(x))}
例子
viper.intersection([1,2,3], [4,3,2]) // [2,3]
根据函数移除数组中的元素并返回移除元素
viper.remove = (arr, fn) => Array.isArray(arr) ? arr.filter(fn).reduce((acc, val) => {
arr.splice(arr.indexOf(val), 1);
return acc.concat(val)
}, []) : []
例子
viper.remove([1, 2, 3, 4], n => n % 2 == 0) // [2, 4]
随机获取数组或字符串中一个元素
viper.sample = arr => arr[Math.floor(Math.random() * arr.length)]
例子
viper.sample([1,2,3]) // 2
从数组中获取n个随机元素,最大为数组的大小
viper.sampleSize = ([...arr], n = 1) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr.slice(0, n);
};
例子
viper.sampleSize([1, 2, 3], 2); // [1,3]
viper.sampleSize([1, 2, 3], 4); // [1,3,2]
chunk分割成指定大小的数组, 如果不能整分,剩余的会组成一个新的数组
viper.chunk = (arr, size) => Array.from({length: Math.ceil(arr.length / size)}, (v, i) =>{
return arr.slice(i * size, i * size + size)
})
例子
viper.chunk([1, 2, 3, 4, 5], 2); // [[1,2],[3,4],[5]]
删除数组中错误的值 false, null, 0, “”, undefined, and NaN
viper.compact = arr => arr.filter(Boolean)
例子
viper.compact([1, false, NaN]) // [1]
统计数组中某个值出现的次数
viper.countOccurrences = (arr, val) => arr.reduce((a, v)=>(v === val ? a + 1 : a + 0), 0);
例子
viper.countOccurrences([1, 1, 2, 1, 2, 3], 1); // 3
深度平铺数组 转换为一维数组
viper.deepFlatten = arr => [].concat(...arr.map(v => (Array.isArray(v) ? deepFlatten(v) : v)))
例子
viper.deepFlatten([1, [2], [[3], 4], 5]); // [1,2,3,4,5]
创建指定唯度的数组 默认为1
viper.flatten = (arr, depth =1) => depth != 1
? arr.reduce((a, v) => a.concat(Array.isArray(v) ? flatten(v, depth - 1) : v), [])
: arr.reduce((a, v) => a.concat(v), [])
例子
viper.flatten([1, [2, [3, [4, 5], 6], 7], 8], 2); // [1, 2, 3, [4, 5], 6, 7, 8]
viper.flatten([1, [2], 3, 4]); // [1, 2, 3, 4]
从数组右边开始对每个元素执行指定函数
viper.forEachRight = (arr, callback) => arr.slice(0).reverse().forEach(callback)
例子
viper.forEachRight([1, 2, 3, 4], val => console.log(val)); // '4', '3', '2', '1'
数组去重
viper.distinctValuesOfArray = arr => [...new Set(arr)]
例子
viper.distinctValuesOfArray([1, 2, 2, 3, 4, 4, 5]); // [1,2,3,4,5]
从右删除指定位置n的元素, n默认为1
viper.dropRight = (arr, n = 1) => arr.slice(0, -n)
};
例子
viper.dropRight([1, 2, 3]); // [1,2]
viper.dropRight([1, 2, 3], 2); // [1]
viper.dropRight([1, 2, 3], 42); // []
返回数组中的每个第n个元素
viper.everyNth = (arr, nth) => arr.filter((e, i) => i % nth === nth - 1);
例子
viper.everyNth([1, 2, 3, 4, 5, 6], 2); // [ 2, 4, 6 ]
返回数组中唯一值
viper.filterNonUnique = arr => arr.filter( i => arr.indexOf(i) === arr.lastIndexOf(i))
例子
viper.filterNonUnique([1, 2, 2, 3, 4, 4, 5]); // [1,3,5]
11111111
返回数组中val出现的所有索引
viper.indexOfAll = (arr, val) => {
const indices = []
arr.forEach((el, i) => el === val && indices.push(i))
return indices
}
例子
viper.indexOfAll([1, 2, 3, 1, 2, 3], 1); // [0,3]
viper.indexOfAll([1, 2, 3], 4); // []
返回除最后一个数组外的所有元素
viper.initial = (arr) => arr.slice(0, -1)
例子
initial([1, 2, 3]); // [1,2]
初始化一个包含指定范围中的数字的数组
viper.initializeArrayWithRange = (end, start = 0, step = 1) => Array.from({length : Math.ceil((end + 1 -start) / step)}).map((v, i)=> i * step + start)
例子
viper.initializeArrayWithRange(7, 3); // [3,4,5,6,7]
viper.initializeArrayWithRange(9, 0, 2); // [0,2,4,6,8]
初始化指定长度并填充初始值
viper.initializeArrayWithValues = (n, val = 0) => Array(n).fill(val)
例子
viper.initializeArrayWithValues(5, 2); // [2,2,2,2,2]
是否排序 正序返回1 降序返回-1 未排序返回0
viper.isSorted = arr => {
const direction = arr[0] > arr[1] ? -1 : 1;
for(let [i, val] of arr.entries()){
if(i === arr.length - 1){
return direction
} else if((val - arr[i + 1]) * direction > 0){
return 0
}
}
}
例子
viper.isSorted([0, 1, 2, 2]); // 1
viper.isSorted([4, 3, 2]); // -1
viper.isSorted([4, 3, 5]); // 0
使用分隔符和结束符拼接所有数组中的元素并返回拼接好的字符串
viper.join = (arr, separator = ',', end = separator) => arr.reduce((acc, val, i) => i == arr.length - 2 ? acc + val + end : i == arr.length - 1 ? acc + val : acc + val + separator, '')
};
例子
viper.join(['pen', 'pineapple', 'apple', 'pen'], ',', '&'); // "pen,pineapple,apple&pen"
viper.join(['pen', 'pineapple', 'apple', 'pen'], ','); // "pen,pineapple,apple,pen"
viper.join(['pen', 'pineapple', 'apple', 'pen']); // "pen,pineapple,apple,pen"
返回最后一个元素
viper.last = arr => arr[arr.length - 1];
例子
viper.last([1, 2, 3]); // 3
返回多个可迭代对象中长度最长的一个
viper.longestItem = (...vals) => [...vals].sort((a, b) => b.length - a.length)[0]
例子
viper.longestItem(...['a', 'ab', 'abc'], 'abcd'); // 'abcd'
viper.longestItem([1, 2, 3], [1, 2], [1, 2, 3, 4, 5]); // [1, 2, 3, 4, 5]
viper.longestItem([1, 2, 3], 'foobar'); // 'foobar'
从提供的数组中返回n个最大元素 如果n大于或等于提供的数组长度,则返回原始数组(按降序排列)
viper.maxN = (arr, n = 1) => [...arr].sort((a,b) => b - a).slice(0, n)
例子
viper.maxN([1, 2, 3]); // [3]
viper.maxN([1, 2, 3], 2); // [3,2]
从提供的数组中返回n个最小元素。如果n大于或等于提供的数组长度,则返回原始数组(按升序排序)
viper.minN = (arr, n =1) => [...arr].sort((a, b) => a - b).slice(0, n)
例子
viper.minN([1, 2, 3]); // [1]
viper.minN([1, 2, 3], 2); // [1,2]
返回数组的第n个元素
viper.nthElement = (arr, n = 0) => (n > 0 ? arr.slice(n , n + 1) : arr.slice(n)[0])
例子
viper.nthElement(['a', 'b', 'c'], 1); // 'b'
viper.nthElement(['a', 'b', 'b'], -3); // 'a'
根据所提供的函数对每个元素的真实性将这些元素分成两个数组
viper.partition = (arr, fn) =>{
return arr.reduce(
(acc, val, i, arr) => {
acc[fn(val, i, arr) ? 0 : 1].push(val)
return acc
},
[[], []]
)
}
例子
const users = [{ user: 'barney', age: 36, active: false }, { user: 'fred', age: 40, active: true }];
viper.partition(users, o => o.active); // [[{ 'user': 'fred', 'age': 40, 'active': true }],[{ 'user': 'barney', 'age': 36, 'active': false }]]
返回的过滤指定的值后的数组
viper.pull = (arr, ...args) => {
let argState = Array.isArray(args[0]) ? args[0] : args;
let pulled = arr.filter((v, i) => !argState.includes(v));
arr.length = 0;
pulled.forEach(v => arr.push(v))
}
例子
let myArray = ['a', 'b', 'c', 'a', 'b', 'c'];
viper.pull(myArray, 'a', 'c'); // myArray = [ 'b', 'b' ]
返回的过滤指定的索引后的数组, 返回过滤的值
viper.pullAtIndex = (arr, pullArr) => {
let removed = [];
let pulled = arr.map((v, i) => pullArr.includes(i) ? removed.push(v) : v).filter((v, i)=> !pullArr.includes(i))
arr.length = 0;
pulled.forEach(v => arr.push(v))
return removed
}
};
例子
let myArray = ['a', 'b', 'c', 'd'];
let pulled = viper.pullAtIndex(myArray, [1, 3]); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
改变原始数组以过滤出指定的值,返回删除的元素
viper.pullAtValue = (arr, pullArr) => {
let removed = [],
pushToRemove = arr.forEach((v, i)=> (pullArr.includes(v) ? removed.push(v) : v)),
mutateTo = arr.filter((v,i) => !pullArr.includes(v));
arr.length = 0
mutateTo.forEach(v => arr.push(v))
return removed
}
例子
let myArray = ['a', 'b', 'c', 'd'];
let pulled = viper.pullAtValue(myArray, ['b', 'd']); // myArray = [ 'a', 'c' ] , pulled = [ 'b', 'd' ]
根据条件过滤一个对象数组,同时过滤未指定的键
viper.reducedFilter = (data, keys, fn) => data.filter(fn).map(el => keys.reduce((acc, key) => {
acc[key] = el[key]
return acc
}, {}))
例子
const data = [
{
id: 1,
name: 'john',
age: 24
},
{
id: 2,
name: 'mike',
age: 50
}
];
viper.reducedFilter(data, ['id', 'name'], item => item.age > 24); // [{ id: 2, name: 'mike'}]
洗牌数组
viper.shuffle = ([...arr]) => {
let m = arr.length;
while (m) {
const i = Math.floor(Math.random() * m--);
[arr[m], arr[i]] = [arr[i], arr[m]];
}
return arr
}
例子
const foo = [1, 2, 3];
viper.shuffle(foo); // [2,3,1], foo = [1,2,3]
获取数组交集
viper.similarity = (arr, values) => arr.filter(v => values.includes(v))
};
例子
viper.similarity([1, 2, 3], [1, 2, 4]); // [1,2]
返回两个数组之间的不同值
viper.symmetricDifference = (a, b) => {
const sA = new Set(a),
sB = new Set(b);
return [...a.filterx(x => !sB.has(x)), ...b.filter(x => !sA.has(x))]
}
例子
viper.symmetricDifference([1, 2, 3], [1, 2, 4]); // [3,4]
返回数组中除第一个元素外的所有元素
viper.tail = arr => (arr.length > 1 ? arr.slice(1) : arr)
例子
viper.tail([1, 2, 3]); // [2,3]
viper.tail([1]); // [1]
返回从头开始删除n个元素的数组
viper.take = (arr, n = 1) => arr.slice(0 ,n)
例子
viper.take([1, 2, 3], 5); // [1, 2, 3]
viper.take([1, 2, 3], 0); // []
返回从最后删除n个元素的数组
viper.takeRight = (arr, n = 1) => arr.slice(arr.length - n, arr.length)
例子
viper.takeRight([1, 2, 3], 2); // [ 2, 3 ]
viper.takeRight([1, 2, 3]); // [3]
返回数组合集
viper.union = (a ,b) => Array.from(new Set([...a, ...b]))
例子
viper.union([1, 2, 3], [4, 3, 2]); // [1,2,3,4]
创建一个排除所有给定值的数组
viper.without = (arr, ...args) => arr.filter(v => args.indexOf(v) === -1)
例子
viper.without([2, 1, 2, 3], 1, 2); // [3]
根据原始数组中的位置进行分组创建新的数组 如果参数数组的长度不一致,那么在未找到值的地方使用undefined
viper.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])
})
}
例子
viper.zip(['a', 'b'], [1, 2], [true, false]); // [['a', 1, true], ['b', 2, false]]
viper.zip(['a'], [1, 2], [true, false]); // [['a', 1, true], [undefined, 2, false]]
给定一组有效的属性标识符和一个值数组,返回一个将属性关联到值的对象,未找到值的地方使用undefined
viper.zipObject = (props, values) => props.reduce((obj, prop, index) => ((obj[prop] = values[index]), obj), {})
};
例子
viper.zipObject(['a', 'b', 'c'], [1, 2]); // {a: 1, b: 2, c: undefined}
viper.zipObject(['a', 'b'], [1, 2, 3]); // {a: 1, b: 2}
求数字数组的平均数
viper.average = arr => arr.reduce((acc, val) => acc + val, 0) / arr.length
例子
viper.average([1,2,3]) // 2
复制字符串到剪贴板
viper.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)
}
}
例子
viper.copyToClipboard('111') // 111复制到了剪贴板
返回当前页面的滚动位置
viper.getScrollPosition = (el = window) =>({
x: el.pageXOffset !== undefined ? el.pageXOffset : el.scrollLeft,
y: el.pageYOffset !== undefined ? el.pageYOffset : el.scrollTop
})
例子
viper.getScrollPosition() // {x: 3, y: 6023}
返回指定元素的CSS规则的值
viper.getStyle = (el, ruleName) => getComputedStyle(el)[ruleName]
例子
viper.getStyle(document.querySelector('p'), 'font-sise') // 16px
元素是否包含类
viper.hasClass = (el, className) => el.classList.contains(className)}
例子
viper.hasClass(document.querySelector('p.box'), 'box') // ture
隐藏指定所有元素
viper.hide = (...el) => [...el].forEach( e => (e.style.display = 'node'))s
例子
viper.hide(document.querySelectorAll('img')) // 页面中的所以img被隐藏
平滑返回顶部
viper.scrollToTop = () => {
const c = document.documentElement.scrollTop || document.body.scrollTop
if(c > 0){
window.requestAnimationFrame(scrollToTop)
window.scrollTo(0, c - c / 8)
}
}
例子
viper.scrollToTop() // 页面返回顶部
设置元素的css样式
viper.steStyle = (el, ruleNmae, val) =>{ el.style[ruleNmae] = val }
例子
viper.steStyle(document.querySelector('p'), 'font-size', '18px') // 第一个p元素字体大小为18像素
显示所有指定的元素
viper.show = (...el) => [...el].forEach(e.style.display = '')
例子
viper.show(document.querySelectorAll('img')) // 显示所有img标签
切换元素类名
viper.toggleClass = (el, className) => el.classList.toggleClass(className)
例子
viper.toggleClass(document.querySelector('div.box'), 'box') // 切换box类名
确保函数只调用一次
viper.once = fn => {
let called = false;
return function(...args){
if(called) return
called = true
return fn.call(this, args)
}
}
例子
document.body.addEventListener('click', once(()=>{console.log(111)})) // 函数只会调用一次
防抖
viper.debounce = (func, wait, immediate) => {
var timeout, result;
return function () {
var context = this;
var args = arguments;
if (timeout) clearTimeout(timeout);
if (immediate) {
// 如果已经执行过,不再执行
var callNow = !timeout;
timeout = setTimeout(function(){
timeout = null;
}, wait)
if (callNow) func.apply(context, args)
}
else {
timeout = setTimeout(function(){
func.apply(context, args)
}, wait);
}
}
}
例子
var count = 1;
var container = document.body;
function getUserAction() {
console.log(count)
};
container.onmousemove = viper.debounce(getUserAction, 1000);
阶乘
viper.factorial = n => n <= 1 ? 1 : n * factorial(n - 1)
例子
viper.factorial(6) // 720
最大公约数
viper.gcd = (x, y) => !y ? x : gcd(y, x % y);
例子
viper.gcd(8, 36) // 4
viper.gcd(...[8, 36, 12]) // 4
是否在指定范围内
viper.inRange = (n, start, end = null) => {
if(end && start > end) end = [start, (start = end)][0]
return end == null ? n >= 0 && n < start : n >= start && n < end
}
例子
viper.inRange(3, 4, 5) // false
viper.inRange(3, 4) // true
数值2能否否能整除数值1
viper.isDivisible = (first, second) => second % first === 0
例子
viper.isDivisible(3, 9) // true
随机获取指定范围内的整数
viper.randomIntegerInRange = (min, max) => Math.floor(Math.random() * ( max - min + 1)) + min
例子
viper.randomIntegerInRange(2, 5) // 3
随机获取指定范围内的小数
viper.randomNumberInRange = (min, max) => Math.random() * (max - min) + min
例子
viper.randomNumberInRange(2, 10); // 6.0211363285087005
返回指定位数的小数,省略第二个参数 四舍五入为整数
viper.round = (n, decimals=0) => Number(`${Math.round(`${n}e${decimals}`)}e-${decimals}`)
例子
viper.round(4.22) // 4
viper.round(1.005, 2); // 1.01
从对象中挑选与给定键对应的键值对
viper.pick = (obj, arr) => arr.reduce((acc, curr)=> (curr in obj && (acc[curr] = obj[curr]), acc), {})
例子
viper.pick({ a: 1, b: '2', c: 3 }, ['a', 'c']); // { 'a': 1, 'c': 3 }
删除指定属性外的其他属性
viper.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]
}
})
return obj
}
例子
const testObj = { a: 1, b: 2, children: { a: 1, b: 2 } };
viper.cleanObj(testObj, ['a'], 'children'); // { a: 1, children : { a: 1}}
反转key和value
viper.invertKeyValues = obj => Object.keys(obj).reduce((acc, key)=> {
acc[obj[key]] = key
return acc
},{})
例子
viper.invertKeyValues({ name: 'John', age: 20 }); // { 20: 'age', John: 'name' }
小写所有key
viper.lowercaseKeys = obj => Object.keys(obj).reduce((acc, key)=> {
acc[key.toLowerCase()] = obj[key]
return acc
},{})
例子
const myObj = { Name: 'Adam', sUrnAME: 'Smith' };
const myObjLower = viper.lowercaseKeys(myObj); // {name: 'Adam', surname: 'Smith'};
合并两个或者多个对象
viper.merge = (...objs) => [...objs].reduce(
(acc, obj) => Object.keys(obj).reduce(
(a, k) => {
acc[k] = acc.hasOwnProperty(k) ? [].concat(acc[k]).concat(obj[k]) : obj[k];
return acc
},{}),
{}
)
例子
const object = {
a: [{ x: 2 }, { y: 4 }],
b: 1
};
const other = {
a: { z: 3 },
b: [2, 3],
c: 'foo'
};
viper.merge(object, other); // { a: [ { x: 2 }, { y: 4 }, { z: 3 } ], b: [ 1, 2, 3 ], c: 'foo' }
获取对象、数组、字符串的大小
viper.size = val => Array.isArray(val) ? val.length : val && typeof val === 'object' ? val.size || val.length || Object.keys(val).length : typeof val === 'string' ? new Blob([val]).size : 0
例子
viper.size([1, 2, 3, 4, 5]); // 5
viper.size('size'); // 4
viper.size({ one: 1, two: 2, three: 3 }); // 3
将数值字符串转换成数组
viper.digitize = n => [...`${n}`].map(i => parseInt(i))
例子
viper.digitize(123); // [1, 2, 3]
生成一个字符串所有的排列组合
viper.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)), [])
}
例子
viper.anagrams('abc'); // ['abc','acb','bac','bca','cab','cba']
返回字节大小
viper.byteSize = str => new Blob([val]).size
例子
viper.byteSize('😀'); // 4
viper.byteSize('Hello World'); // 11
首字母大写
viper.Capitalize = ([first, ...rest], lowerRest = false) => first.toUpperCase() + (lowerRest ? rest.join('').toLowerCase() : rest.join(''))
例子
viper.Capitalize('fooBar'); // 'FooBar'
viper.Capitalize('fooBar', true); // 'Foobar'
大写单词的每个首字母
viper.capitalizeEveryWord = str => str.replace(/\d[a-z]/g, char => char.toUpperCase())
例子
viper.capitalizeEveryWord('hello world!'); // 'Hello World!'
首字母小写
viper.decapitalize = ([first, ...rest], upperRest = false) => first.toLowerCase() + (upperRest ? rest.join('').toUpperCase() : rest.join(''));
例子
viper.decapitalize('FooBar'); // 'fooBar'
viper.decapitalize('FooBar', true); // 'fOOBAR'
转义HTML
viper.escapeHTML = str => str.replace(
/[&<>'"]/g,
tag => ({
'&': '&',
'<': '<',
'>': '>',
"'": ''',
'"': '"'
})([tag] || tag)
)
例子
viper.escapeHTML('<a href="#">Me & you</a>'); // '<a href="#">Me & you</a>'
将驼峰字符改成字符串
viper.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()
例子
viper.fromCamelCase('someDatabaseFieldName', ' '); // 'some database field name'
viper.fromCamelCase('someLabelThatNeedsToBeCamelized', '-'); // 'some-label-that-needs-to-be-camelized'
viper.fromCamelCase('someJavascriptProperty', '_'); // 'some_javascript_property'
用指定的字符替换除最后指定个字符以外的所有字符
viper.mask = (str, num = 4, mask = '*') => {
return ('' + str).slice(0, -num).replace(/./g, mask) + ('' + str).slice(-num)
}
例子
viper.mask(1234567890); // '******7890'
viper.mask(1234567890, 3); // '*******890'
viper.mask(1234567890, -4, '$'); // '$$$$567890'
检查回文
viper.palindrome = (str) => {
const s = str.toLowerCase().replace(/[\W_]/g, '')
return (
s === s.split().reverse().join('')
)
}
例子
viper.palindrome('taco cat'); // true
反转字符串
viper.reverseString = (str) => [...str].reverse().join('')
例子
viper.reverseString('viper') // repiv
按字母顺序排列字符串中的字符
viper.sortString = (str) => [...str].sort((a, b) => a.localeCompare(b)).join('')
例子
viper.sortString('cabbage'); // 'aabbceg'
将字符串改为驼峰字符串
viper.toCamelCase = (str) => {
let s =
str &&
str
.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g)
.map(x => x.slice(0, 1).toUpperCase() + x.slice(1).toLowerCase())
.join('');
return s.slice(0, 1).toLowerCase() + s.slice(1)
}
例子
viper.toCamelCase('some_database_field_name'); // 'someDatabaseFieldName'
viper.toCamelCase('Some label that needs to be camelized'); // 'someLabelThatNeedsToBeCamelized'
viper.toCamelCase('some-javascript-property'); // 'someJavascriptProperty'
截断字符串在后面添加…
viper.truncateString = (str, num) => {
return str.length > num ? str.slice(0, num > 3 ? num -3 : num) + '...' : str
}
例子
truncateString('boomerang', 7); // 'boom...'
反转义HTML字符串
viper.unescapeHTML = (str) => str.replace(
/&|<|>|'|"/g,
tag =>
({
'&': '&',
'<': '<',
'>': '>',
''': "'",
'"': '"'
}[tag] || tag)
)
例子
viper.unescapeHTML('<a href="#">Me & you</a>'); // '<a href="#">Me & you</a>'
校验字符是否是json
viper.isValidJSON = obj => {
try {
JSON.parse(obj)
} catch (e) {
return false
}
}
例子
viper.isValidJSON('{"name":"Adam","age":20}'); // true
viper.isValidJSON('{"name":"Adam",age:"20"}'); // false
viper.isValidJSON(null); // true
获取类型 undefined、null、NaN 直接返回 其他返回小写的构造函数的名称
viper.getType = v => v !== v ? 'NaN' : v === undefined ? 'undefined' : v === null ? 'null' : v.constructor.name.toLowerCase()
例子
viper.getType(new Set([1, 2, 3])); // 'set'
viper.getType({}) // object
viper.getType([]) // array
返回第一个非null非undefined的值
viper.coalesce = (...args) => args.find( _ => ![undefined, null].includes(_))
例子
viper.coalesce(null, undefined, '', NaN, 'Waldo'); // ""
返回第一个符合过滤函数的值
viper.coalesceFactory = valid => (...args) => args.find(valid)
例子
const customCoalesce = coalesceFactory(_ => ![null, undefined, '', NaN].includes(_));
viper.customCoalesce(undefined, null, NaN, '', 'Waldo'); // "Waldo"
将3位数的hex颜色值转换成6为数的值
viper.extendHex = shortHex => '#' + shortHex.slice(shortHex.startsWith('#') ? 1 : 0).split('').map(x => x + x ).join('')
例子
viper.extendHex('#03f'); // '#0033ff'
返回对象包含url上的参数
viper.getURLParams = url => url.match(/([^?=&]+)(=([^&]*))/g).reduce(
(a, v) => ((a[v.slice(0, v.indexOf('='))] = v.slice(v.indexOf('=') + 1 )),a), {}
)
例子
viper.getURLParams('http://url.com/page?name=Adam&surname=Smith'); // {name: 'Adam', surname: 'Smith'}
hex转rgb
viper.hexToRGB = hex => {
let alpha = false,
h = hex.slice(hex.startsWith('#') ? 1 : 0);
if (h.length === 3) h = [...h].map(x => x + x).join('');
else if (h.length === 8) alpha = true;
h = parseInt(h, 16);
return (
'rgb' +
(alpha ? 'a' : '') +
'(' +
(h >>> (alpha ? 24 : 16)) +
', ' +
((h & (alpha ? 0x00ff0000 : 0x00ff00)) >>> (alpha ? 16 : 8)) +
', ' +
((h & (alpha ? 0x0000ff00 : 0x0000ff)) >>> (alpha ? 8 : 0)) +
(alpha ? `, ${h & 0x000000ff}` : '') +
')'
);
}
例子
viper.hexToRGB('#27ae60ff'); // 'rgba(39, 174, 96, 255)'
viper.hexToRGB('27ae60'); // 'rgb(39, 174, 96)'
viper.hexToRGB('#fff'); // 'rgb(255, 255, 255)'
随机生成hex颜色值
viper.randomHexCode = () => {
let n = ((Math.random() * 0xfffff) | 0).toString(16)
return '#' + (n.length !== 6 ? ((Math.random() * 0xf) | 0).toString(16) + n : n)
}
例子
viper.randomHexCode() // "#e34155"
RGB转hex色值
viper.RGBToHex = (r, g, b) => ((r << 16) + (g << 8) + b).toString(16).padStart(6, '0')
例子
viper.RGBToHex(255, 165, 1); // 'ffa501'
返回函数运行时长
viper.timeTaken = callback => {
console.time('timeTaken')
const cb = callback()
console.timeEnd('timeTaken')
return cb
}
例子
viper.timeTaken(() => Math.pow(2, 10)); // 1024, (logged): timeTaken: 0.02099609375ms
使用crypto API 生成UUID 符合RFC4122 版本 4
viper.UUIDGeneratorBrowser = () => {
return ([1e7] + -1e3 + -4e3 + -8e3 + -1e11).replace(/[018]/g, c =>
(c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16)
)
}
例子
viper.UUIDGeneratorBrowser() // '7982fcfe-5721-4632-bede-6000885be57d'
邮箱验证
viper.validEmail = 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)
例子
viper.validEmail('[email protected]') // true