Recently, I met a requirement to compare the difference between two arrays. Each item of the array is an object, including the change of array length. The increase and deletion can be detected, and the result can be displayed in the form of a table. Online to find the relevant articles are too simple array is pure numbers in the case, is not applicable here, there is no way to hand pull a function to achieve it, here to make a record.

Without further ado, let’s say we now have two arrays as follows:

/ / before the change
const arr1 = [{
  name: 'jen'.age: 19.city: 'Beijing'
}, {
  name: 'cui flower'.age: 17.city: 'Shanghai'
}, {
  name: 'the dog left'.age: 30.city: 'hangzhou'
}];
/ / after the change
const arr2 = [{
  name: 'Handsome ratio'.age: 25.city: 'xi 'an'
}, {
  name: 'Handsome ratio'.age: 35.city: 'chengdu'
}];
Copy the code

As you can see, the contents of these two arrays are completely different. Our requirement is to compare the changes in these two arrays. How to do this?

Specific ideas

  1. We declare a function, set its parameters to receive the array before and after the change, and initialize the return value of the function
function comparison(previous, current) {
  // Previous indicates the array before the change, current indicates the array after the change
  
  // Define the return value of the function
  const result = [];
  return result;
}
Copy the code

In order to render the data easily, we need to use an array to render the data easily. In addition, each item in the array is a set of changes. The length of the array is the number of changes in the group, which we will show later.

  1. Now we’re going to roll out the concrete implementation, but first we get some values:
  // Get the number of groups changed. Len represents how many groups of data were changed
  const len = Math.max(arr1.length, arr2.length);
  // Get the array to iterate over
  const loopArr = arr1.length > arr2.length ? arr1 : arr2;
  // Get another array for comparison
  const preArr = arr1.length > arr2.length ? arr2 : arr1;
Copy the code

Len is a variable that stores how many groups of data are changed. If loopArr is used for traversal, there will be no missing cases. LoopArr is the same length as Len, so you only need to store the other group of data with preArr.

  1. Now let’s start with the logical part

Make a judgment before comparison. If there is no change, return directly. This section can also be mentioned in front of the function to judge

// Return with no change
if (JSON.stringify(arr1) === JSON.stringify(arr2)) {
  return;
}
Copy the code

Json. stringify is used for comparison. Note that the object property values are undefined and functions, as json. stringify ignores them

We initialize the change for each set of data:

for (let i = 0; i < len; i++) {
  result[i] = [];
}
Copy the code

Here we use the for loop to initialize it. It is a bit awkward to write in the vue method. I wonder if there is a simpler way to write it

And then we’ll start matching. Straight up

loopArr.forEach((item, index) = > {
  for( const key in item) {
    // Add and delete cases default to empty objects
    preArr[index] || (preArr[index] = {});
    // If not, define an object and push it into the array
    if(item[key] ! == preArr[index][key]) {const changedItem = {
        fieldName: key, / / the field name
        preValue: arr1[index][key] || ' '.// The value before the change is null by default
        currentValue: arr2[index][key] || ' '.// The changed value
      }
      result[index].push(changedItem)
    }
  }
});
Copy the code

The comparison results

So that’s the logical part of it, so let’s do itcomparison(arr1, arr2)Check out the results:You can see that the changed values are detected, as well as additions and deletions. Here we set it to null, otherwise undefined will be displayed

Finally, we will present the results in the form of a table, which can compare the differences more intuitively. Since each object in my requirement array is a group of rules, the changes of rules can be detected no matter they are added, deleted or modified

The complete code

Finally, attach the complete code:

 / / before the change
  const arr1 = [{
    name: 'jen'.age: 19.city: 'Beijing'
  }, {
    name: 'cui flower'.age: 17.city: 'Shanghai'
  }, {
    name: 'the dog left'.age: 30.city: 'hangzhou'
  }];
  / / after the change
  const arr2 = [{
    name: 'Handsome ratio'.age: 25.city: 'xi 'an'
  }, {
    name: 'Handsome ratio'.age: 35.city: 'chengdu'
  }];
  
  
function comparison(previous, current) {
  // Previous indicates the array before the change, current indicates the array after the change
  
  // Define the return value of the function
  const result = [];
  // Get the number of groups changed. Len represents how many groups of data were changed
  const len = Math.max(arr1.length, arr2.length);
  // Get the array to iterate over
  const loopArr = arr1.length > arr2.length ? arr1 : arr2;
  // Get another array for comparison
  const preArr = arr1.length > arr2.length ? arr2 : arr1;
  
  // Return with no change
  if (JSON.stringify(arr1) === JSON.stringify(arr2)) {
    return;
  }
  // Initialize changes to each set of data
  for (let i = 0; i < len; i++) {
    result[i] = [];
  }
  // walk through the differences
  loopArr.forEach((item, index) = > {
    for( const key in item) {
      // Add and delete cases default to empty objects
      preArr[index] || (preArr[index] = {});
      // If not, define an object and push it into the array
      if(item[key] ! == preArr[index][key]) {const changedItem = {
          fieldName: key, / / the field name
          preValue: arr1[index][key] || ' '.// The value before the change is null by default
          currentValue: arr2[index][key] || ' '.// The changed value
        }
        result[index].push(changedItem)
      }
    }
  });
  return result;
}
  
Copy the code

Here is the end of the whole process, like a friend to help like it.