likes
comments
collection
share

高频的处理数据方法(复杂数据结构)汇总,过滤,去重,拆分,扁平化数组,排序等

作者站长头像
站长
· 阅读数 14

本文涉及工作中常用到的数据处理方法(汇总,过滤,去重,拆分,扁平化数组,排序等),逐一实现,其中绝大部分都是针对复杂的数据结构的处理,后续仍然会陆续补充关于数组(复杂对象)的处理,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)

  • arrayflat() 方法将在给定的数组中使用。
  • 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)