最近遇到一个需求,需要比较两个数组的差异,数组的每一项都是一个对象,包括数组长度的变更,要求增加和删除都能检测到,将结果用表格的形式展现出来;网上寻找到相关的文章都是过于简单的数组里面是纯数字的情况,在这里并不适用,没办法只好手撸一个函数来实现一下,在此做个记录。
废话不多说直接开干,假设现在有两个数组如下:
const arr1 = [{
name: '阿花',
age: 19,
city: '北京'
name: '翠花',
age: 17,
city: '上海'
name: '狗剩',
age: 30,
city: '杭州'
const arr2 = [{
name: '大帅比',
age: 25,
city: '西安'
name: '老帅比',
age: 35,
city: '成都'
可以看到这两个数组内容是完全不一样的,我们的需求是比较这两个数组的变更,那么如何来实现呢?
我们先声明一个函数,设置好对应的形参用来接收变更前后的数组,并初始化函数的返回值
function comparison(previous, current) {
const result = [];
return result;
为什么这里选择用数组来作为返回值呢,其实想象一下就能明白,上面我们要求要用表格的形式展现出来,用数组可以方便渲染数据,同时数组的每一项都是一组变更,数组的长度就是变更的组数,这个我们后面会慢慢体现。
现在我们要开始撸具体的实现部分了,在此之前我们先拿到一些值:
const len = Math.max(arr1.length, arr2.length);
const loopArr = arr1.length > arr2.length ? arr1 : arr2;
const preArr = arr1.length > arr2.length ? arr2 : arr1;
为什么要这么写呢,len
这个变量存储的是变更了多少组数据,同时拿loopArr
用来遍历就不会出现遗漏的情况,因为loopArr
的长度和len
是相等的,这是只需要用preArr
存一下另一组数据就好了。
现在开始我们的逻辑部分
比对之前先做一层判断,若没有发生变更就直接return掉,这一块也可以提到函数前面一进来就判断
if (JSON.stringify(arr1) === JSON.stringify(arr2)) {
return;
这里使用的是JSON.stringify来对比,要注意对象属性值为undefined和函数的情况,因为JSON.stringify会忽略掉它们
函数执行到这里就说明发生了变更,我们先初始化每一组数据的变更:
for (let i = 0; i < len; i++) {
result[i] = [];
这里使用的是for循环来初始化,在vue的方法里写的话看着有点别扭,不知道有没有其他更简洁的写法,知道的小伙伴可以留个言哈
然后就开始我们的比对了,直接上码
loopArr.forEach((item, index) => {
for( const key in item) {
preArr[index] || (preArr[index] = {});
if (item[key] !== preArr[index][key]) {
const changedItem = {
fieldName: key,
preValue: arr1[index][key] || '',
currentValue: arr2[index][key] || '',
result[index].push(changedItem)
到这里逻辑部分就写完了,我们来执行comparison(arr1, arr2)
看看结果:
可以看到变更的值都检测到了,同时增加和删除也能检测到,这里我们把它设置为空了,不然会显示undefined
最后我们再用表格的形式来展现结果,可以更加直观的对比差异
由于我的那个需求数组里每一个对象都是一组规则,现在不管是增加删除还是修改,都可以检测到规则的变更了
最后附上完整代码:
const arr1 = [{
name: '阿花',
age: 19,
city: '北京'
name: '翠花',
age: 17,
city: '上海'
name: '狗剩',
age: 30,
city: '杭州'
const arr2 = [{
name: '大帅比',
age: 25,
city: '西安'
name: '老帅比',
age: 35,
city: '成都'
function comparison(previous, current) {
const result = [];
const len = Math.max(arr1.length, arr2.length);
const loopArr = arr1.length > arr2.length ? arr1 : arr2;
const preArr = arr1.length > arr2.length ? arr2 : arr1;
if (JSON.stringify(arr1) === JSON.stringify(arr2)) {
return;
for (let i = 0; i < len; i++) {
result[i] = [];
loopArr.forEach((item, index) => {
for( const key in item) {
preArr[index] || (preArr[index] = {});
if (item[key] !== preArr[index][key]) {
const changedItem = {
fieldName: key,
preValue: arr1[index][key] || '',
currentValue: arr2[index][key] || '',
result[index].push(changedItem)
return result;
到这里整个过程就结束了,喜欢的朋友帮忙点个赞吧。