高频的处理数据方法(复杂数据结构)汇总,过滤,去重,拆分,扁平化数组,排序等
本文涉及工作中常用到的数据处理方法(汇总,过滤,去重,拆分,扁平化数组,排序等),逐一实现,其中绝大部分都是针对复杂的数据结构的处理,后续仍然会陆续补充关于数组(复杂对象)的处理,up自己记录,也方便小伙伴们使用~~
一、过滤
1、基础数据结构
const data = [
{
name: 'zhangsan',
age: 22,
address: {
city: 'New York',
country: 'USA'
}
},
{
name: 'lisi',
age: 42,
address: {
city: 'Paris',
country: 'France'
}
},
{
name: 'wangwu',
age: 17,
address: {
city: 'London',
country: 'UK'
}
}
];
const filteredhandle = data.filter(item => item.address.country === 'USA');
console.log(filteredhandle);
// Output: [{ name: 'zhangsan', age: 25, address: { city: 'New York', country: 'USA' } }]
2、复杂数据结构
// 根据id 筛选出两个数组中id不等的一项
const data1 = [
{
id: 1,
name: 'zhangsan',
age: 25,
address: {
city: 'New York',
country: 'USA'
}
},
{
id: 2,
name: 'lisi',
age: 32,
address: {
city: 'Paris',
country: 'France'
}
},
{
id: 3,
name: 'Bob',
age: 40,
address: {
city: 'London',
country: 'UK'
}
}
];
const data2 = [
{
id: 2,
job: 'Doctor'
},
{
id: 3,
job: 'Lawyer'
},
{
id: 4,
job: 'Engineer'
}
];
const filteredhandlefilteredhandle = data1.filter(item1 => !data2.some(item2 => item2.id === item1.id));
console.log(filteredhandle);
// Output: [{ id: 1, name: 'zhangsan', age: 25, address: { city: 'New York', country: 'USA' } }]
3、根据一个数组对象过滤另一个数组对象
一、获取array1中包含array2的 id 字段的信息
let array1 = [
{ id: 1, name: 'zhangsan', age: 20, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 2, name: 'lisi', age: 21, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 3, name: 'wangwu', age: 22, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 4, name: 'zhaoliu', age: 23, hobby: ['sleep', 'shopping', 'drinking'] }
]
let array2 = [
{ id: 3, name: 'wangwu' },
{ id: 4, name: 'zhaoliu' }
]
// 预期输出
[
{ id: 3, name: 'wangwu', age: 22, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 4, name: 'zhaoliu', age: 23, hobby: ['sleep', 'shopping', 'drinking'] }
]
let arr = array1.filter( item => {
return array2.find( value => {
return value.id === item.id
})
})
console.log(arr)
// 输出结果
[
{ id: 3, name: 'wangwu', age: 22, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 4, name: 'zhaoliu', age: 23, hobby: ['sleep', 'shopping', 'drinking'] }
二、获取array1中不包含array2的 id 字段的信息
let array1 = [
{ id: 1, name: 'zhangsan', age: 20, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 2, name: 'lisi', age: 21, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 3, name: 'wangwu', age: 22, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 4, name: 'zhaoliu', age: 23, hobby: ['sleep', 'shopping', 'drinking'] }
]
let array2 = [
{ id: 3, name: 'wangwu' },
{ id: 4, name: 'zhaoliu' }
]
// 预期输出
[
{ id: 1, name: 'zhangsan', age: 20, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 2, name: 'lisi', age: 21, hobby: ['sleep', 'shopping', 'drinking'] },
]
let arr = array1.filter( item => {
return !array2.find( value => {
return value.id === item.id
})
})
console.log(arr)
// 输出结果
[
{ id: 1, name: 'zhangsan', age: 20, hobby: ['sleep', 'shopping', 'drinking'] },
{ id: 2, name: 'lisi', age: 21, hobby: ['sleep', 'shopping', 'drinking'] },
二、去重
1、基本数据结构去重
首先是基本数据结构去重的例子:
const data = [1, 2, 3, 2, 4, 3, 5];
const uniqueData = [...new Set(data)];
console.log(uniqueData);
// Output: [1, 2, 3, 4, 5]
一个包含重复数字的数组。使用 Set
来创建一个不包含重复项的集合。然后,使用扩展运算符 ...
将集合转换为数组。
2、复杂数据结构去重(1)
接下来是复杂对象去重的例子:
const data = [
{
id: 1,
name: 'zhangsan'
},
{
id: 2,
name: 'lisi'
},
{
id: 1,
name: 'zhangsan'
},
{
id: 3,
name: 'zhaoliu'
}
];
const uniqueData = Array.from(new Set(data.map(item =>
// 补充一下,这里也可以直接用id 不一定非要序列化
JSON.stringify(item)))).map(item => JSON.parse(item));
console.log(uniqueData);
// Output: [{ id: 1, name: 'zhangsan' }, { id: 2, name: 'lisi' }, { id: 3, name: 'zhaoliu' }]
在这个例子中,我们有一个包含重复对象的数组。由于 Set
只能用于基本数据类型的去重,所以我们需要先将对象转换为字符串。我们使用数组的 map
方法和 JSON.stringify
方法来将每个对象转换为 JSON 字符串。
然后使用 Set
来创建一个不包含重复项的集合。接着,我们使用 Array.from
方法将集合转换为数组。
再次使用数组的 map
方法和 JSON.parse
方法将 JSON 字符串转换回对象。
2、复杂数据结构去重(2)
reduce
方法去重
const data = [
{
id: 1,
name: 'zhangsan'
},
{
id: 2,
name: 'lisi'
},
{
id: 1,
name: 'zhangsan'
},
{
id: 3,
name: 'zhaoliu'
}
];
const uniqueData = data.reduce((acc, cur) => {
if (!acc.some(item => JSON.stringify(item) === JSON.stringify(cur))) {
acc.push(cur);
}
// 这样写也可以哦
// if (!acc.some(item => item.id === cur.id) {
// acc.push(cur);
// }
return acc;
}, []);
console.log(uniqueData);
// Output: [{ id: 1, name: 'zhangsan' }, { id: 2, name: 'lisi' }, { id: 3, name: 'zhaoliu' }]
2、复杂数据结构去重(3)
rfilter
+ findIndex
去重
const data = [
{
id: 1,
name: 'zhangsan'
},
{
id: 2,
name: 'lisi'
},
{
id: 1,
name: 'zhangsan'
},
{
id: 3,
name: 'zhaoliu'
}
];
const uniquePeople = data.filter((person, index) => {
// findIndex返回的是索引
// 第一次 匹配元素 返回0 等于当前索引 用filter 过滤 条件为真 所以元素保留
// 第二次 匹配元素 返回1 等于当前索引 用filter 过滤 条件为真 所以元素保留
// 第三次 匹配元素 返回2 等于当前索引 用filter 过滤 条件为真 所以元素保留
// 第三次 匹配元素 返回1 不等于当前索引 当前的index为3 因为它等于第一个元素了 所以元素被过滤掉了
return data.findIndex(p => p.name === person.name && p.age === person.age) === index;
});
三、扁平化数组
1、数组扁平化(reduce)
数组扁平化是指将一个多维数组转换为一个一维数组的过程。
const data = [1, [2, [3, [4, 5]]]];
const flatten = arr => arr.reduce((acc, cur) => acc.concat(Array.isArray(cur) ? flatten(cur) : cur), []);
const flattenedList = flatten(data);
console.log(flattenedList);
// Output: [1, 2, 3, 4, 5]
在这个例子中,我们定义了一个多维数组 data
,并使用递归函数 flatten
来进行扁平化处理。flatten
函数使用数组的 reduce
方法来累加一个一维数组。在回调函数中,我们检查当前元素是否为数组。如果是,则递归调用 flatten
函数来扁平化该元素;否则,直接将该元素推入累加器中。
2、数组扁平化(for + concat)
const arr = [1, [2, [3, [4, 5]]]];
function flatten(arr) {
for (let i = 0; i < arr.length; i++) {
if (Array.isArray(arr[i])) {
result = result.concat(flatten(arr[i]))
} else {
result.push(arr[i])
}
}
return arr
}
3、数组扁平化(flat())
flat():方法创建一个新数组,其中所有子数组元素以递归方式连接到特定深度。
语法:array.flat(depth)
- array :
flat()
方法将在给定的数组中使用。 - depth:可选参数,指定展平的深度,默认情况下,深度为
1
。
const array = [[1, 2], [3, 4], 5];
console.log(array.flat()); // [ 1, 2, 3, 4, 5 ]
flat()
方法删除数组中的空槽
const array = [[1, 2], , [3, 4], 5];
console.log(array.flat()); // [ 1, 2, 3, 4, 5 ]
在一些复杂的场合,数组的层级不单一比较复杂的情况下,可借助参数
Infinity
,将所有层级的数组展平。
const arrVeryDeep = [[1, [2, 2, [3, [4, [5, [6]]]]], 1]];
console.log(arrVeryDeep.flat(Infinity)); // [ 1, 2, 2, 3, 4, 5, 6, 1 ]
4、数组扁平化(扩展运算符)
let arr = [1, [2, [3, 4]]];
function flatten(arr) {
while (arr.some(i =>
Array.isArray(i))) {
arr = [].concat(...arr);
}
return arr;
}
console.log(flatten(arr)); // [1, 2, 3, 4,5]
四、排序
up之前写过一篇关于排序的算法,里面包含很多排序的经典案例以及详细解法,下面附上时光传送门-
额外补充一种排序方法(sort)
方法就地对数组的元素进行排序,并返回对相同数组的引用。默认排序是将元素转换为字符串,然后按照它们的 UTF-16 码元值升序排序,
这话的意思就是说,她和我们想象的排序不太一样,sort排序是按照 UTF-16 码元值升序排序,举个例子。
const array1 = [1, 30, 4, 21, 100000];
array1.sort();
console.log(array1);、
// 大概大家理解的排序结果是 1, 4, 21, 30, 100000
// 但实际结果是:
// Expected output: Array [1, 100000, 21, 30, 4]
那么如果我们需要1, 4, 21, 30, 100000的排序结果该如何写呢? 官网提供了很不错的写法
如果想按照其他规则进行排序,就需要提供比较函数,该函数要比较两个值,然后返回一个用于说明这两个值的相对顺序的数字。比较函数应该具有两个参数 a 和 b,其返回值如下: 若 a 小于 b,在排序后的数组中 a 应该出现在 b 之前,则返回一个小于 0 的值 若 a 等于b,则返回 0 若 a 大于 b,则返回一个大于 0 的值
简单点就是:比较函数两个参数a和b,a-b返回升序,b-a返回降序
let array = [1, 30, 4, 21, 100000];
array.sort(function(a,b){
return a - b;
})
console.log(array);// [ 1, 4, 21, 30, 100000]
在稀疏数组上使用 sort()
空槽会被移动到数组的末尾。
console.log(["a", "c", , "b"].sort()); // ['a', 'b', 'c', empty]
console.log([, undefined, "a", "b"].sort()); // ["a", "b", undefined, empty]
另外官网针对sort排序的性能,额外做了说明:
使用 map 改善排序(参考MDN)
转载自:https://juejin.cn/post/7270912998928023604