如何动态比较 javascript 数组中的差异



>我有一个反应更新表单,我希望区分表单数据和当前数据,以找出动态更改的内容。

问题总结

查找 2 个嵌套对象之间的最小差异。并输出已更改属性路径的数组。例如,如果部门列表中索引为 0 的department_id发生变化,而其余部分保持不变 - 算法应输出 ['部门']。

示例数据:

我的数据通常是这样的(这是一个简化的形式,但数据有不同的深度,如下所示(:

{id:115,
departments: [{
department_id:1,
department_name:"asd"}],
name: 'Test project',
}

假设用户决定向对象添加一个部门,我希望能够以这种方式检测更改:

changes = ['departments']

或者如果用户更改了名称:

changes = ['name']

这里的另一个挑战是我希望在我的表单中使用这个函数,这意味着比较应该能够处理不同的键和数据深度

编辑:

数据1 :

creation_date: "2020-06-16"
customer_information: Array(1)
0: 1
project_status: 1
sales_department: 1
sales_project_name: "helloss2sasdssssssssssss"
userProfile: Array(2)
0: 1

数据2:

creation_date: "2020-06-16"
customer_information: Array(1)
0: 1
project_status: 1
sales_department: 1
sales_project_name: "helloss2"
userProfile: Array(2)
0: 1
1: 2

这里调用的函数:

const data1 = action.original
const data2 = action.final
const difference = Object.keys(data1).filter((key)=>!walk(data1[key],data2[key]))
console.log(difference)

这是差异的控制台日志:

[] 

预期:

['userProfile' , 'sales_project_name']

简单的朴素递归函数遍历,深度等于并在分支发生变化时返回。 筛选匹配的键。

data1 = {
creation_date: "2020-06-16",
customer_information: [1],
project_status: 1,
sales_department: 1,
sales_project_name: "helloss2sasdssssssssssss",
userProfile: [1],
version: 1
}
data2 = {
creation_date: "2020-06-16",
customer_information: [1],
project_status: 1,
sales_department: 1,
sales_project_name: "helloss2",
userProfile: [1, 2],
version: 2
}
walk = (node1, node2) => {
// different types, return false
if (typeof node1 !== typeof node2) return false
if (node1 && node2 && typeof node1 === 'object') {
const keys = Object.keys(node1)
// if type object, check same number of keys and walk on node1, node2
return keys.length === Object.keys(node2).length &&
keys.every(k => walk(node1[k], node2[k]))
}
// not object and types are same, return if node1 is equal to node2
return node1 === node2
}
console.log(
Object.keys(data1).filter((key) => !walk(data1[key], data2[key]))
)

如果您不想使用任何库来比较嵌套对象,您可以简单地转换为 JSON 并比较字符串。

假设您要比较对象,它可能如下所示:

function getUnequalKeys(object1, object2) {
let unequalKeys = [];
for (let key in object1) {
if (object1.hasOwnProperty(key) 
&& (
!object2.hasOwnProperty(key)
|| JSON.stringify(object1[key]) !== JSON.stringify(object2[key])
)
) {
unequalKeys.push(key);
}
}
for (let key2 in object2) {
if (object2.hasOwnProperty(key2) && !object1.hasOwnProperty(key2)) {
unequalKeys.push(key2);
}
}
return unequalKeys;
}

这将返回两个对象中不存在或具有不同值的所有一级键。

编辑:它本质上的作用如下: 循环遍历对象 1 中的每个键。检查对象 2 中是否存在相同的键。如果它不存在,则表示键不相等,因此条件为 true,并且键被添加到不相等键列表中。如果 object2 中确实存在该键,请创建两个值的 JSON 字符串并比较这些字符串。如果字符串不同,则表示它们具有不同的值。在这种情况下,还要将键添加到不相等键数组中。 现在我们已经检查了对象 1 的所有键。

作为最后一步,遍历 object2 的所有键并检查它们是否在 object1 中不存在,在这种情况下,还要将它们添加到不相等键数组中。

最新更新