常用数据处理函数
日期格式化函数
将传入的标准化日期对象转换为指定的格式
实现代码:
const dateFormat = (dateInput, format) => {
// 获取日期
let day = dateInput.getDate()
// 获取月份
let month = dateInput.getMonth() + 1
// 获取年份
let year = dateInput.getFullYear()
// 将传入的格式化日期中对应格式的字符串进行替换
format = format.replace(/yyyy/, year)
format = format.replace(/mm/, month)
format = format.replace(/dd/, day)
}不使用临时变量,交换 a、b 的值
a = a + b
b = a - b
a = a - b实现数组的乱序输出
主要思路就是每轮循环随机产生一个索引值,然后按照顺序将数组中的元素与该索引值对应的元素交换。
TIP
需要注意的是,每个元素产生的索引值要在该元素之后的位置。
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9]
for (let i = 0; i < arr.length; i++) {
const randomIdx = Math.round(Math.random() * (arr.length - 1 - i)) + i
;[arr[i], arr[randomIdx]] = [arr[randomIdx], arr[i]]
}实现数组元素求和
- 循环实现
function sum(arr) {
let res = 0
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res += sum(arr[i])
} else {
res += arr[i]
}
}
return res
}- reduce 实现
function sum2(arr) {
return arr.reduce((pre, cur) => {
if (Array.isArray(cur)) {
return pre + sum2(cur)
}
return pre + cur
}, 0)
}数组扁平化
- 递归实现
const flat1 = (arr) => {
let res = []
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
res = res.concat(flat1(arr[i]))
} else {
res.push(arr[i])
}
}
return res
}- reduce 迭代
const flat2 = (arr) => {
return arr.reduce((pre, cur) => {
return pre.concat(Array.isArray(cur) ? flat2(cur) : cur)
}, [])
}- 扩展运算符
扩展运算符会将数组摊开,子数组会被暴露给 concat 方法。
concat 方法调用后,会将子数组中的元素添加到新数组中,多次执行后,便得到了扁平化的数组。
const flat3 = (arr) => {
while (arr.some((item) => Array.isArray(item))) {
arr = [].concat(...arr)
}
return arr
}- flat
调用 ES6 中的 flat 方法来实现数组扁平化。
flat 方法的语法:arr.flat([depth])
depth 是可以传递数组的展开深度(不填默认为 1),即展开一层数组。参数为 Infinity 时,可以对任意层数的数组进行扁平化。
const flat4 = (arr) => {
return arr.flat(Infinity)
}- toString + Split
数组原型上自带方法 toString() ,可以将数组转化成由逗号分隔的字符串。再调用 split 方法以逗号为分割,将字符串转化为数组。
const flat5 = (arr) => {
return arr.toString().split(',').map(Number)
}实现数组去重
- 使用 Set 集合
const dedup1 = (arr) => {
return [...new Set(arr)]
}- 使用 Map
const dedup2 = (arr) => {
const map = new Map()
const res = []
for (const i of arr) {
if (!map.has(i)) {
res.push(i)
map.set(i, 1)
}
}
return res
}实现数组的 flat 方法
在手写扁平化的基础上加一个 depth 参数,只会对数组进行 depth 层扁平化,这里用 reduce 实现。
const myFlat = (arr, depth) => {
if (depth <= 0) {
return arr
}
return arr.reduce((pre, cur) => {
if (Array.isArray(cur)) {
return pre.concat(myFlat(cur, depth - 1))
}
return pre.concat(cur)
}, [])
}实现数组的 push 方法
语法: arr.push(element1, element2, ..., elementN)
参数:element1, element2, ..., elementN:要添加到数组末尾的一个或多个元素。
返回值:返回值是一个表示修改后的数组的新长度的整数。
- 自定义函数实现
const myPush = (arr, ...elements) => {
const { length } = arr
const newLength = length + elements.length
for (let i = 0; i < elements.length; i++) {
arr[length + i] = elements[i]
}
return newLength
}- 数组原型实现
Array.prototype.push = function (...elements) {
const { length } = this
const newLength = length + elements.length
for (let i = 0; i < elements.length; i++) {
this[length + i] = elements[i]
}
return newLength
}实现数组的 filter 方法
filter 方法用于创建一个新数组,其中包含通过指定函数测试的所有元素。
语法:const newArray = array.filter(callback(element[, index[, array]])[, thisArg])
参数:
- callback:表示对每个元素进行测试的函数,它可以接收三个参数:
- element:当前正在被测试的元素。
- index(可选):当前元素的索引。
- array(可选):调用 filter 方法的原始数组。
- thisArg(可选):可在 callback 函数中使用的 this 值。
返回值: filter 方法返回一个新数组,其中包含通过测试函数的元素。
该方法不会改变原数组
Array.prototype._filter = function(fn) {
if (typeof fn !== "function") {
throw Error('参数必须是一个函数');
}
const res = [];
for (let i = 0, len = this.length; i < len; i++) {
fn(this[i]) && res.push(this[i]);
}
return res;
}实现数组的map方法
map 方法用于创建一个新数组,其中包含对原始数组的每个元素应用指定函数后的结果。
语法: const newArray = array.map(callback(element[, index[, array]])[, thisArg])
参数:
- callback:表示对每个元素进行操作的函数,它可以接收三个参数:
- element:当前正在被操作的元素。
- index(可选):当前元素的索引。
- array(可选):调用 map 方法的原始数组。
- thisArg(可选):可在 callback 函数中使用的 this 值。
返回值: map 方法返回一个新数组,其中包含对原始数组的每个元素应用指定函数后的结果。
该方法不会改变原数组
Array.prototype._map = function(fn) {
if (typeof fn !== "function") {
throw Error('参数必须是一个函数');
}
const res = [];
for (let i = 0, len = this.length; i < len; i++) {
res.push(fn(this[i]));
}
return res;
}实现字符串的 repeat 方法
repeat 方法用于重复字符串。
repeat(s, n),输入字符串s,以及其重复的次数,输出重复后的结果,例如输入abc,2,输出abcabc。
可以通过 new Array(n + 1) 来创建一个长为 n + 1 的空数组。
然后使用 join 方法,以 str 为分隔符,将这个数组连接起来,就可以得到 str 重复 n 次后的字符串。
function repeat(str, n) {
return new Array(n + 1).join(str)
}实现字符串翻转
思路比较简单,先通过 split() 方法,以空值为分隔符,将字符串分割为字符数组。
然后对数组调用 reverse() 方法,得到翻转后的字符数组。
最后通过 join() 方法,以控制为分隔符,把这个字符数组连接起来,返回连接后的字符串。
function reverse(str) {
return str.split('').reverse().join('')
}将数字每千分位用逗号隔开
- 无小数情况
首先使用 toString() 方法,将数字转换为字符串。
接着使用一个正则表达式,匹配每三个数字的位置。
解析 URL Params 为对象
const urlData =
'http://www.domain.com/?user=anonymous&id=123&id=456&city=%E5%8C%97%E4%BA%AC&enabled'
const getParams = (url) => {
const queryString = url.split('?')[1]
const paramsArray = queryString.split('&')
const paramsObj = {}
paramsArray.forEach((param) => {
const [key, value] = param.split('=')
if (!paramsObj[decodeURIComponent(key)]) {
paramsObj[decodeURIComponent(key)] = decodeURIComponent(value)
} else {
paramsObj[decodeURIComponent(key)] = [].concat(
paramsObj[decodeURIComponent(key)],
decodeURIComponent(value)
)
}
if (!value) {
paramsObj[decodeURIComponent(key)] = true
}
})
return paramsObj
}
Blog of Desain