开发中后台项目的时候,前端最多的就是 JS 的数据处理,过滤、转换、合并等等,这里收集了工作中常见的数据处理的方式,并持续更新。

数组对象去重

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let params = [
{
id: 1,
name: 'Lina'
},
{
id: 2,
name:'Bob'
},
{
id:1,
name:'Lina'
}
]

let resultParams = Object.values(params.reduce((item, next) => {
item[next.id] = next
return item
},{}))

console.log(resultParams)

// [{id: 1, name: 'Lina'},{id: 2, name: 'Bob'}]

数组对象过滤

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
let paramsList = [
{
id: 1,
name: 'Lina',
isEnable: true
},
{
id: 2,
name: 'Bob',
isEnable: false
},
{
id: 3,
name: 'Tom',
isEnable: true
}
]

let enableList = paramsList.filter(_item => _item.isEnable)

console.log(enableList)

// [{id: 1, name: 'Lina', isEnable: true}, {id: 3, name: 'Tom', isEnable: true}]

对象转换为数组

1
2
3
4
5
6
7
let o = {id: 1, name: 'Lina'}

Object.values(o)
Object.keys(o)

// ["id", "name"]
// [1, "Lina"]

数组对象转为大对象

1
2
3
4
5
6
7
8
let attrArrayWithObj = [{aa: '11', bb: '22', cc: '33'}]

let attrWithObj = {}
for(let t of attrArrayWithObj ){
attrWithObj = {...attrWithObj, ...t}
}

// {aa: "11", bb: "22", cc: "33"}

提取数组对象中特定的值作为一个数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let arr = [
{
'id': '1',
'name': '小红',
},
{
'id': '2',
'name: '小白',
},
{
'id': '3',
'name': '小黄',
}
];

// 使用map()生成数组
let new_arr = arr.map(obj => {return obj.name})

// 输出 ['小红','小白','小黄']

SKU组合算法(用于商品或购物)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/**
* @description SUK组合
* @param {[[],[]..]} chunks 传入不同的属性值数组进行组合
*/
const SKUCombine = (arr: any[]) => {
if(arr.length){
if (arr[0].children)
arr = arr.map((item: any) => {
return item = item.children
})
if (arr.length === 1)
return arr[0]
else {
let arrySon = []
arr[0].forEach((_: any, index: React.ReactText) => {
arr[1].forEach((_: any, index1: React.ReactText) => {
arrySon.push([].concat(arr[0][index], arr[1][index1]))
})
})
arr[0] = arrySon
arr.splice(1, 1)
// 递归
return SKUCombine(arr)
}
}
}

找出数组对象中符合条件的某项的某个值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
let arr = [
{
id: 1,
name: 'Lina'
},
{
id: 2,
name:'Bob'
},
{
id:3,
name:'Tom'
}
]

arr.find(__item => __item.name==='Tom').id

// 3

数组对象按属性对object分类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
let people = [
{ name: 'Alice', age: 21 },
{ name: 'Max', age: 20 },
{ name: 'Jane', age: 20 }
]

function groupBy(objectArray, property) {
return objectArray.reduce(function (acc, obj) {
let key = obj[property];
if (!acc[key]) {
acc[key] = []
}
acc[key].push(obj)
return acc
}, {})
}

let groupedPeople = groupBy(people, 'age')

// { 20: [{ name: 'Max', age: 20 },{ name: 'Jane', age: 20 }], 21: { name: 'Alice', age: 21 } }

一维数组转为键值对象

1
2
3
4
5
6
7
8
9
10
11
12
let arr = [11,22,33,44,55,66]
arr.reduce((a, b, idx) =>{
if (idx % 2) {
a[Math.ceil(idx / 2) - 1].lat = b
return a
} else
return [...a, {lng: b}]
},[])

// [{lng: 11, lat: 22},
// {lng: 33, lat: 44},
// {lng: 55, lat: 66}]

二维数组转为一维数组

1
2
3
4
5
6
7
let flattened = [[0, 1], [2, 3], [4, 5]].reduce(
function(a, b) {
return a.concat(b);
},
[]
);
// flattened is [0, 1, 2, 3, 4, 5]

js 数组过滤空值(undefined、null、""、0、false、NaN)

1
const arr = [undefined, null, "", 0, false, NaN, 1, 2].filter(Boolean);

向上递归找所有父级

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/**
* arr1: 树形数组;
* id: 指定的id
* */
function familyTree (arr1, id) {
var temp = []
var forFn = function (arr, id) {
for (var i = 0; i < arr.length; i++) {
var item = arr[i]
if (item.id === id) {
temp.push(item)
forFn(arr1, item.parentId)
break
} else {
if (item.children) {
forFn(item.children, id)
}
}
}
}
forFn(arr1, id)
return temp
}

借助lodash和moment.js获取日期段的每一天

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 先安装moment
// npm i moment
// 再安装Lodash,可以用它内部封装好的方法,简单实用
// npm i lodash
const moment = require("moment");
const _ = require("lodash");

// 假设需要查询2019-06-25至2019-12-31号之间每一天的00:00至23:59这个时间段的数据
// 将时间转换为moment时间格式
const start = "2019-06-25"; // 开始时间
const start_time = moment(start);
console.log(moment(start_time)); // moment("2019-06-25T00:00:00.000")

const end = "2019-12-31";
const end_time = moment(end).endOf("d");
console.log(end_time); // endOf("d")为当天的结束时间 moment("2019-12-31T23:59:59.999")

// 开始计算这两个时间段相差的天数
const diff_times = end_time.diff(start_time,"d");
console.log(diff_times); // 189

// lodash中内置的循环器,可以指定循环次数
// 再定义一个数组,用来存放相差的每一天日期
const arr = [];
_.times(diff_times, i => {
//每次重新初始化开始时间,因为我碰到了深拷贝的问题
const new_start_time = moment(start_time);

//数组下标从0开始,可以用它进行每次的天数递增
arr.push(new_start_time.add(i, "days").format("YYYY-MM-DD"));
});

console.log(arr);

/* [ '2019-06-25','2019-06-26','2019-06-27','2019-06-28', ...] */

同时检验字符串和中文字符数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/**
* maxByte: number 最大字符数
* */
export const validatorByte = (rule, value, callback, maxByte: number) => {
try {
let str = value
str = str.replace(/[\u4e00-\u9fa5]/g, 'OO')
if(str.length > maxByte)
throw new Error(`最多输入${maxByte}个字符,${Math.floor(maxByte / 2)}个汉字`);
else
callback()
} catch (err) {
callback(err)
}
}

判断一个字符串是否为数字

简单的判断字符串是否为数字的方法就是利用isNaN(),如果返回true,则该字符串不为数字,否则为数字