javascript - 根据外部对象属性删除对象上的数组元素
问题描述
我有一个对象,我想从它的一个属性中删除元素,该属性是基于外部对象的匹配属性的对象数组。
这使用 npm deep-diff 来比较两个对象。
我的问题是在 combineDuplicateRecords 内部,它将每条记录与每条记录进行比较,在身份数组中创建重复项。所以身份最终看起来像:
[{
id: "111",
identities: [
{
id: "111"
},
{
id: "111"
},
{
id: "222"
},
{
id: "222"
},
{
id: "333"
},
{
id: "333"
}
]
}]
当我真的希望它看起来像这样时:
[{
id: "111",
identities:[
{
id: "222"
},
{
id: "333"
}
]
}]
代码:
var requestRecords = [
{
vid: "12345",
id: "12345",
email: "gft@test.com",
firstName: "GrandFathering",
lastName: "TestMN",
postalCode: "55443-2410",
phone: "123-456-7890",
key: "1212"
},
{
vid: "121212",
id: "12222",
email: "g233@test.com",
firstName: "NoMatch",
lastName: "NoMatchFound",
postalCode: "43233-2410",
phone: "123-456-7890",
key: "121233"
},
{
vid: "111",
id: "111",
email: "ffffft@test.com",
firstName: "samebatch",
lastName: "samebatch",
postalCode: "5545",
phone: "123-456-7890",
key: "3333",
},
{
vid: "222",
id: "222",
email: "ffffft@test.com",
firstName: "samebatch",
lastName: "samebatch",
postalCode: "5545",
phone: "123-456-7890",
key: "4444",
},
{
vid: "333",
id: "333",
email: "ffffft@test.com",
firstName: "samebatch",
lastName: "samebatch",
postalCode: "5545",
phone: "123-456-7890",
key: "55",
}
];
combineDuplicateRecords = (arrayOfRecords, prefilter) => {
const recordsToRemove = [];
arrayOfRecords.forEach(firstRecord => {
arrayOfRecords.forEach((secondRecord, index) => {
if (
firstRecord.firstName == secondRecord.firstName &&
firstRecord.lastName == secondRecord.lastName &&
firstRecord.dateOfBirth == secondRecord.dateOfBirth &&
firstRecord.phone == secondRecord.phone &&
firstRecord.postalCode == secondRecord.postalCode &&
firstRecord.id !=
secondRecord.id
) {
const identities = [];
let identity = {};
this.preserveExisitingIdentities(secondRecord, identities);
this.preserveExisitingIdentities(firstRecord, identities);
identity = this.setIdentityDifferencesBetweenRecords(
firstRecord,
secondRecord,
prefilter,
identity
);
identities.push(identity);
firstRecord["identities"] = identities;
recordsToRemove.push(index);
}
});
});
[...new Set(recordsToRemove)].forEach(index => {
arrayOfRecords.splice(index, 1);
});
return arrayOfRecords;
};
preserveExisitingIdentities = (record, identities) => {
if (record.hasOwnProperty("identities")) {
record.identities.forEach(identity => {
identities.push(identity);
});
}
return identities;
};
setIdentityDifferencesBetweenRecords = (
firstIdentity,
secondIdentity,
prefilter,
identity
) => {
const differences = Diff(firstIdentity, secondIdentity, prefilter);
let i = differences.length;
while (i--) {
if (differences[i].path[0] == "vid") {
differences.splice(i, 1);
}
if (differences[i].path[0] == "identities") {
differences.splice(i, 1);
}
//we only want to keep the differences so we remove kind D
if (differences[i]?.kind == "D") {
differences.splice(i, 1);
}
}
differences.forEach(diff => {
identity[diff.path[0]] = diff.lhs;
});
return identity;
};
console.log(JSON.stringify(combineDuplicateRecords(requestRecords)));
解决方案
获取每个内部 id 并将它们保存在数据结构中,然后用于Array#find
查找整个对象并将其插入回identities
const array = [
{
id: "111",
identities: [
{
id: "111"
},
{
id: "111"
},
{
id: "222"
},
{
id: "222"
},
{
id: "333"
},
{
id: "333"
}
]
}
]
const cleanObject = (obj) => {
const allIds = obj.identities.map(({ id }) => id)
const mainId = obj.id
const uniqueIds = new Set(allIds)
uniqueIds.delete(mainId)
const nextIdentities = [...uniqueIds].map(currId => {
return obj.identities.find(({ id }) => currId === id)
})
obj.identities = nextIdentities
return obj
};
const el = array.map(entry => {
return cleanObject(entry)
})
console.log(el)
推荐阅读
- reactjs - 是否有一种干净的方法可以在 useEffect 中触发多个连续的 setTimeouts?
- api - 在 Python 请求模块中,在 POST 方法中,响应没有按预期获得,但 POSTMAN 工具中的相同操作按预期工作
- javascript - 我直接从教程中复制的简单代码不起作用,Javascript Notepad++
- php - 无法让 GETTEXT 在 MAMP 服务器和 Windows 10 上使用 PHP
- node.js - POST net::ERR_EMPTY_RESPONSE axios
- visual-studio-code - VS Code:更改菜单栏颜色
- sql - 如何显示连续日期
- r - R将操作写入函数并迭代
- https - Bazel 远程缓存不适用于证书/TLS
- javascript - 从授权服务器收到无效响应。Xero 与 Bagisto 的集成