Skip to content
On this page

常用数据处理函数 ​

日期格式化函数 ​

将传入的标准化日期对象转换为指定的格式

实现代码:

js
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

需要注意的是,每个元素产生的索引值要在该元素之后的位置。

js
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]]
}

实现数组元素求和 ​

  1. 循环实现
js
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
}
  1. reduce 实现
js
function sum2(arr) {
  return arr.reduce((pre, cur) => {
    if (Array.isArray(cur)) {
      return pre + sum2(cur)
    }
    return pre + cur
  }, 0)
}

数组扁平化 ​

  1. 递归实现
js
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
}
  1. reduce 迭代
js
const flat2 = (arr) => {
  return arr.reduce((pre, cur) => {
    return pre.concat(Array.isArray(cur) ? flat2(cur) : cur)
  }, [])
}
  1. 扩展运算符

扩展运算符会将数组摊开,子数组会被暴露给 concat 方法。

concat 方法调用后,会将子数组中的元素添加到新数组中,多次执行后,便得到了扁平化的数组。

js
const flat3 = (arr) => {
  while (arr.some((item) => Array.isArray(item))) {
    arr = [].concat(...arr)
  }
  return arr
}
  1. flat

调用 ES6 中的 flat 方法来实现数组扁平化。

flat 方法的语法:arr.flat([depth])

depth 是可以传递数组的展开深度(不填默认为 1),即展开一层数组。参数为 Infinity 时,可以对任意层数的数组进行扁平化。

js
const flat4 = (arr) => {
  return arr.flat(Infinity)
}
  1. toString + Split

数组原型上自带方法 toString() ,可以将数组转化成由逗号分隔的字符串。再调用 split 方法以逗号为分割,将字符串转化为数组。

js
const flat5 = (arr) => {
  return arr.toString().split(',').map(Number)
}

实现数组去重 ​

  1. 使用 Set 集合
js
const dedup1 = (arr) => {
  return [...new Set(arr)]
}
  1. 使用 Map
js
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 实现。

js
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:要添加到数组末尾的一个或多个元素。

返回值:返回值是一个表示修改后的数组的新长度的整数。

  1. 自定义函数实现
js
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
}
  1. 数组原型实现
js
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:表示对每个元素进行测试的函数,它可以接收三个参数:
  1. element:当前正在被测试的元素。
  2. index(可选):当前元素的索引。
  3. array(可选):调用 filter 方法的原始数组。
  • thisArg(可选):可在 callback 函数中使用的 this 值。

返回值: filter 方法返回一个新数组,其中包含通过测试函数的元素。

该方法不会改变原数组

js
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:表示对每个元素进行操作的函数,它可以接收三个参数:
  1. element:当前正在被操作的元素。
  2. index(可选):当前元素的索引。
  3. array(可选):调用 map 方法的原始数组。
  • thisArg(可选):可在 callback 函数中使用的 this 值。

返回值: map 方法返回一个新数组,其中包含对原始数组的每个元素应用指定函数后的结果。

该方法不会改变原数组

js
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 次后的字符串。

js
function repeat(str, n) {
  return new Array(n + 1).join(str)
}

实现字符串翻转 ​

思路比较简单,先通过 split() 方法,以空值为分隔符,将字符串分割为字符数组。

然后对数组调用 reverse() 方法,得到翻转后的字符数组。

最后通过 join() 方法,以控制为分隔符,把这个字符数组连接起来,返回连接后的字符串。

js
function reverse(str) {
  return str.split('').reverse().join('')
}

将数字每千分位用逗号隔开 ​

  1. 无小数情况
  • 首先使用 toString() 方法,将数字转换为字符串。

  • 接着使用一个正则表达式,匹配每三个数字的位置。

解析 URL Params 为对象 ​

js
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
}