function diffArr(newArr, oldArr, prop = null) {
// 比较新数组newArr与oldArr的区别,如果是通过对象比较的话,传入比较的prop
// 不传prop的话,默认是普通数组
const deleteArr = []
const addArr = []
if (Object.prototype.toString.call(newArr) !== '[object Array]' || Object.prototype.toString.call(oldArr) !== '[object Array]') {
console.log('应传入数组')
return {
deleteArr,
addArr
}
}
let changeArr = [] // 记录位置改变的数组
const usedArr = [] // 缓存就数组&&新数组都存在的数据在旧数组中的index
let newStartIndex = 0
let newEndIndex = newArr.length - 1
let oldStartIndex = 0
let oldEndIndex = oldArr.length - 1
let lastNewStartIndex = newStartIndex
let lastNewEndIndex = newEndIndex
let lastOldStartIndex = oldStartIndex
let lastOldEndIndex = oldEndIndex
let circleNum = 0
while (newStartIndex <= newEndIndex && oldStartIndex <= oldEndIndex) {
/*console.log('-------------')
console.log(`newStartIndex:${newStartIndex}`)
console.log(`newEndIndex:${newEndIndex}`)
console.log(`oldStartIndex:${oldStartIndex}`)
console.log(`newStartIndex:${newStartIndex}`)*/
if (circleNum > 2) {
console.log('出现死循环,强制退出,请检查')
break
}
if (lastNewStartIndex === newStartIndex
&& lastNewEndIndex === newEndIndex
&& lastOldStartIndex === oldStartIndex
&& lastOldEndIndex === oldEndIndex
) {
++circleNum
}
lastNewStartIndex = newStartIndex
lastNewEndIndex = newEndIndex
lastOldStartIndex = oldStartIndex
lastOldEndIndex = oldEndIndex
if (prop !== null) {
if (!newArr[newStartIndex]?.hasOwnProperty(prop)
|| !oldArr[oldStartIndex]?.hasOwnProperty(prop)
|| !newArr[newEndIndex]?.hasOwnProperty(prop)
|| !oldArr[oldEndIndex]?.hasOwnProperty(prop)
) {
break
}
if (usedArr.includes(oldStartIndex)) {
++oldStartIndex
continue
}
if (usedArr.includes(oldEndIndex)) {
--oldEndIndex
continue
}
if (newArr[newStartIndex][prop] !== oldArr[oldStartIndex][prop]
&& newArr[newEndIndex][prop] !== oldArr[oldEndIndex][prop]
&& oldArr[oldStartIndex][prop] !== newArr[newEndIndex][prop]
&& newArr[newStartIndex][prop] !== oldArr[oldEndIndex][prop]) {
let addFlag = true
for (let i = 0; i < oldArr.length; i++) {
if (usedArr.includes(i)) {
continue
}
if (newArr[newStartIndex][prop] === oldArr[i][prop]) {
addFlag = false
++newStartIndex
usedArr.push(i)
}
}
if (addFlag) {
addArr.push(newArr[newStartIndex])
++newStartIndex
}
} else {
if (newArr[newStartIndex][prop] === oldArr[oldStartIndex][prop]) {
// 如果新旧数组start处相同,继续比较下一个
usedArr.push(oldStartIndex)
if (newStartIndex !== oldStartIndex) {
changeArr.push([oldStartIndex, newStartIndex])
}
++newStartIndex
++oldStartIndex
}
if (newArr[newEndIndex][prop] === oldArr[oldEndIndex][prop]) {
// 如果新旧数组end处相同,继续比较上一个
usedArr.push(oldEndIndex)
if (newEndIndex !== oldEndIndex) {
changeArr.push([oldEndIndex, newEndIndex])
}
--newEndIndex
--oldEndIndex
}
if (oldArr[oldStartIndex][prop] === newArr[newEndIndex][prop]) {
// 如果旧数组开始处与新数组结束处相同
usedArr.push(oldStartIndex)
if (newEndIndex !== oldStartIndex) {
changeArr.push([oldStartIndex, newEndIndex])
}
++oldStartIndex
--newEndIndex
}
if (newArr[newStartIndex][prop] === oldArr[oldEndIndex][prop]) {
// 如果新数组开始处与旧数组结束处相同
usedArr.push(oldEndIndex)
if (newStartIndex !== oldEndIndex) {
changeArr.push([oldEndIndex, newStartIndex])
}
++newStartIndex
--oldEndIndex
}
}
} else {
if (usedArr.includes(oldStartIndex)) {
++oldStartIndex
continue
}
if (usedArr.includes(oldEndIndex)) {
--oldEndIndex
continue
}
if (newArr[newStartIndex] !== oldArr[oldStartIndex]
&& newArr[newEndIndex] !== oldArr[oldEndIndex]
&& oldArr[oldStartIndex] !== newArr[newEndIndex]
&& newArr[newStartIndex] !== oldArr[oldEndIndex]) {
let addFlag = true
for (let i = 0; i < oldArr.length; i++) {
if (usedArr.includes(i)) {
continue
}
if (newArr[newStartIndex] === oldArr[i]) {
usedArr.push(i)
addFlag = false
++newStartIndex
}
}
if (addFlag) {
addArr.push(newArr[newStartIndex])
++newStartIndex
}
} else {
if (newArr[newStartIndex] === oldArr[oldStartIndex]) {
// 如果新旧数组start处相同,继续比较下一个
usedArr.push(oldStartIndex)
if (newStartIndex !== oldStartIndex) {
changeArr.push([oldStartIndex, newStartIndex])
}
++newStartIndex
++oldStartIndex
}
if (newArr[newEndIndex]=== oldArr[oldEndIndex]) {
// 如果新旧数组end处相同,继续比较上一个
usedArr.push(oldEndIndex)
if (newEndIndex !== oldEndIndex) {
changeArr.push([oldEndIndex, newEndIndex])
}
--newEndIndex
--oldEndIndex
}
if (oldArr[oldStartIndex] === newArr[newEndIndex]) {
// 如果旧数组开始处与新数组结束处相同
usedArr.push(oldStartIndex)
if (newEndIndex !== oldStartIndex) {
changeArr.push([oldStartIndex, newEndIndex])
}
++oldStartIndex
--newEndIndex
}
if (newArr[newStartIndex] === oldArr[oldEndIndex]) {
// 如果新数组开始处与旧数组结束处相同
usedArr.push(oldEndIndex)
if (newStartIndex !== oldEndIndex) {
changeArr.push([oldEndIndex, newStartIndex])
}
++newStartIndex
--oldEndIndex
}
}
}
}
if (newStartIndex > newEndIndex && oldStartIndex <= oldEndIndex) {
// 新数组先循环结束,旧数组没有循环结束,剩余的内容就是要删除的
for (let i = oldStartIndex; i <= oldEndIndex; i++) {
if (usedArr.includes(i)) {
continue
}
deleteArr.push(oldArr[i])
}
}
if (oldStartIndex > oldEndIndex && newStartIndex <= newEndIndex) {
// 旧数组先循环结束, 新数组没有循环结束,剩余的内容就是要新增的
for (let i = newStartIndex; i <= newEndIndex; i++) {
addArr.push(newArr[i])
}
}
const changeArrObj = {}
changeArr.forEach(ele => {
changeArrObj[ele] = ele
})
changeArr = Object.values(changeArrObj)
console.log(deleteArr, addArr, changeArr)
return {
deleteArr,
addArr,
changeArr
}
}
日常记录#5对比数组,发回需要添加删除项目
于 2022-09-30 09:35:18 首次发布