js一些工具函数

395 阅读4分钟

1.Array

1.1 判断两个数组是否相等(不考虑顺序)

const isEqual = (a, b) => JSON.stringify([...new Set(a)].sort()) === JSON.stringify([...new Set(b)].sort());

//demo 
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, 3, 2]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false

1.2 判断两个数组是否相等

const isEqual = (a, b) => JSON.stringify(a) === JSON.stringify(b);
// or :
const isEqual = (a, b) => a.length === b.length && a.every((v, i) => v === b[i]);

//demo
isEqual([1, 2, 3], [1, 2, 3]); // true
isEqual([1, 2, 3], [1, '2', 3]); // false

1.3 对象数组转换对象

const toObject = arr => arr.reduce((acc, it, idx) => ((acc[idx] = it), acc), {});
//demo:
const arr = [
  { id: "1", name: "Alpha", gender: "Male" },
  { id: "2", name: "Bravo", gender: "Male" },
  { id: "3", name: "Charlie", gender: "Female" },
]
const obj = toObject(arr)
// log(obj)  
{
  '0': { id: '1', name: 'Alpha', gender: 'Male' },
  '1': { id: '2', name: 'Bravo', gender: 'Male' },
  '2': { id: '3', name: 'Charlie', gender: 'Female' }
}

1.4 字符串数组转换为数字数组

const toNumbers = (arr) => arr.map(Number)

toNumbers(['2', '3', '4'])   // [2, 3, 4]

1.5 按对象数组的属性计数

const countByProp = (arr, prop) => arr.reduce((acc, curr) => ((acc[curr[prop]] = ++acc[curr[prop]] || 1), acc), {})

// demo:
countByProp(
    [
        { branch: 'audi', model: 'q8', year: '2019' },
        { branch: 'audi', model: 'rs7', year: '2020' },
        { branch: 'ford', model: 'mustang', year: '2019' },
        { branch: 'ford', model: 'explorer', year: '2020' },
        { branch: 'bmw', model: 'x7', year: '2020' },
    ],
    'branch'
);
// { 'audi': 2, 'ford': 2, 'bmw': 1 }

1.6 某一元素出现的次数

const countOccurrences = (arr, val) => arr.reduce((acc, item) => (item === val ? acc + 1 : acc), 0);
// or :
const countOccurrences = (arr, val) => arr.filter((item) => item === val).length

1.7 每个元素出现的次数

const countOccurrences = (arr) => arr.reduce((acc, it) => ((acc[it] = ++acc[it] || 1), acc), {})

1.8 获取交集

const getIntersection = (arr1, ...arr) => [...new Set(arr1)].filter((v) => arr.every((b) => b.includes(v)))

//demo
getIntersection([1, 2, 3], [2, 3, 4, 5], [1, 3, 5])  // [3]

1.9 获取并集

const union = ( ... arr ) => [ ...new Set ( arr.flat ( ) ) ]

union([1, 2, 3], [3, 4, 5], [5, 6, 7])  // [1, 2, 3, 4, 5, 6, 7]

1.10 字符串转数组

const str = 'abcdefg'

const arr = str.split('')
//or
const arr = [...str]  // ['a', 'b', 'c', 'd', 'e', 'f', 'g']

1.11 获取所有子集

const getSubsets = arr => arr.reduce((acc, item) => acc.concat(acc.map(k => k.concat(item))), [[]])

//demo
getSubsets([1, 2])  // [[], [1], [2], [1, 2]]

1.12 根据条件区分数组

const partition = (arr, criteria) => arr.reduce((acc, i) => (acc[criteria(i) ? 0 : 1].push(i), acc), [[], []])
//demo
partition([1, 2, 3, 4, 5], (n) => n % 2); // [[1, 3, 5], [2, 4]]

1.13 在元素之间穿插内容

const intersperse = (a, s) => [...Array(2 * a.length - 1)].map((_, i) => (i % 2 ? s : a[i / 2]))

//demo
intersperse(['A', 'B', 'C'], '/')   // ['A', '/', 'B', '/', 'C']

1.14 重复数组指定次数

const repeat = (arr, n) => Array(n).fill(arr).flat()

// demo 
repeat([1, 2, 3], 3); // [1, 2, 3, 1, 2, 3, 1, 2, 3]

1.15 随机排列数组

const shuffle = (arr)=> arr.sort(()=> Math.random() - 0.5)

1.16 数组拆分块

const chunk = (arr, size) => arr.reduce((acc, e, i) => (i % size ? acc[acc.length - 1].push(e) : acc.push([e]), acc), [])

//demo 
chunk([1, 2, 3, 4, 5, 6, 7, 8], 3)  // [[1, 2, 3], [4, 5, 6], [7, 8]]
chunk([1, 2, 3, 4, 5, 6, 7, 8], 4)  // [[1, 2, 3, 4], [5, 6, 7, 8]]

1.17 交换数组项

// i < j
const swapItems = (a, i, j) => (a[i] && a[j] && [...a.slice(0, i), a[j], ...a.slice(i + 1, j), a[i], ...a.slice(j + 1)]) || a

//demo
swapItems([1, 2, 3, 4, 5], 1, 4)  // [1, 5, 3, 4, 2]

1.18 数组去重

const unique = (arr) => [...new Set(arr)]
// or
const unique = (arr) => arr.filter((item, i, array) => array.indexOf(item) === i)
// or
const unique = (arr) => arr.reduce((acc,item)=>(acc.includes(item) || acc.push(item) , acc) , [])

1.19 对象数组去重

 
 const unique = (arr) => {
            const obj = {}
            return arr.reduce((acc, item) => {
                return (obj[item.id] || (obj[item.id] = true && acc.push(item)), acc)
            }, [])
        }
 
 // demo
  const arr = [
            {name: '给我一个div', age: 10, id: 1},
            { name: 'yh', age: 12 , id: 2 },
            { name: 'zhy', age: 6 , id: 2 },
            { name: 'yh',age: 13 , id: 1,},
        ]
  //:      
     [
      {name'给我一个div'age10id1},
      {name'yh'age12id2}   
     ] 

1.20 去重空对象,函数, NAN ...

const unique = (arr) => {
            const obj = {}
            return arr.reduce((acc, value) => {
            obj[typeof value + value] || (obj[typeof value + value] = true) && acc.push(value)
            return acc
        }, [])
      }
      
// demo
 const arr = [6, 6, 'true', true, 'true', true, false, false, undefined, undefined, null, null, NaN, NaN,
            'NaN', 0, 0, {}, {},
            [],
            [],
            function () {},
            function () {}
        ]
 // :
 [6, 'true', true, false, undefined, null, NaN, 'NaN', 0, {}}, Array(0), ƒ()]

2.Date

2.1 日期相差天数

const diffDays = (date, otherDate) => Math.ceil(Math.abs(date - otherDate) / (1000 * 60 * 60 * 24))

//demo
diffDays(new Date('2014-12-19'), new Date('2020-01-01'))  // 1839

2.2 日期相差的月份

const monthDiff = (startDate, endDate) => Math.max(0, (endDate.getFullYear() - startDate.getFullYear()) * 12 - startDate.getMonth() + endDate.getMonth())

//demo
monthDiff(new Date('2020-01-01'), new Date('2021-01-01')); // 12

2.3 时间格式转换

const date = new Date()

date.toLocaleDateString()       // '2022/1/29'
date.toLocaleString()           // '2022/1/29 上午10:10:57'
date.toLocaleTimeString()       // '上午10:10:57'
date.toISOString().slice(0,10)  // '2022-01-29'

2.4 明天的日期

const tomorrow = (d => new Date(d.setDate(d.getDate() + 1)))(new Date())
console.log(tomorrow)  // 2022-01-30T02:37:03.003Z
// or 
const tomorrow1 = new Date(new Date().valueOf() + 1000 * 60 * 60 * 24)
console.log(tomorrow1) // 2022-01-30T02:37:03.003Z

2.5 昨天的日期

const yesterday = (d => new Date(d.setDate(d.getDate() - 1)))(new Date())
console.log(yesterday)
// Or
const yesterday1 = new Date(new Date().valueOf() - 1000 * 60 * 60 * 24)
console.log(yesterday1)

3.Object

3.1 检查多个对象是否相等

const isEqual = (...objects) => objects.every((obj) => JSON.stringify(obj) === JSON.stringify(objects[0]))

//demo
isEqual({ foo: 'bar' }, { foo: 'bar' }); // true
isEqual({ foo: 'bar' }, { bar: 'foo' }); // false

3.2 从键值对创建对象

const toObj = (arr) => Object.fromEntries(arr);
// or
const toObj = (arr) => arr.reduce((acc, item) => ((acc[item[0]] = item[1]), acc), {})

//demo
toObj([
    ['a', 1],
    ['b', 2],
    ['c', 3],
]); // { a: 1, b: 2, c: 3 }

3.3 翻转键值

const invert = (obj) => Object.fromEntries(Object.entries(obj).map(([k, v]) => [v, k])

// demo 
invert({ a: '1', b: '2', c: '3' })  // { 1: 'a', 2: 'b', 3: 'c' }

其他

1.获取URL查询参数

const getParam = (url, param) => new URLSearchParams(new URL(url).search).get(param)

//demo
getParam('http://juejin.cn?name=给我一个div', 'name'); // '给我一个div'

2.随机颜色

 function randomColor() {
            return `#${Math.random().toString(16).slice(2, 8)}`
  }
 //or
 `rgb(${~~(Math.random() * 255)},${~~(Math.random() * 255)},${~~(Math.random() * 255)})`;