我有两个这样的字符串列表:
let previous_id = ["5b7b5498ab3f510e307e7d04", "5b7ae97cc6d75e1331e28d9c", "5b7a0c207fab2722a2081caf"];
let current_id = ["5b7b5498ab3f510e307e7d04", "5b83e3b4412f370bd7b9a05d"];
我想比较两个列表中的所有元素,以便知道列表中仍存在哪个,哪个是新的,以及哪个已被删除。
结果将是:
delete_id = ["5b7ae97cc6d75e1331e28d9c", "5b7a0c207fab2722a2081caf"];
new_id = ["5b83e3b4412f370bd7b9a05d"];
existing_id = ["5b7b5498ab3f510e307e7d04"];
有什么功能吗?
我想避免像这样的多个if条件进行两个循环:
let previous_id = ["5b7b5498ab3f510e307e7d04", "5b7ae97cc6d75e1331e28d9c", "5b7a0c207fab2722a2081caf"];
let current_id = ["5b7b5498ab3f510e307e7d04", "5b83e3b4412f370bd7b9a05d"];
delete_id = [];
new_id = [];
existing_id = [];
for(let item of previous_id){
let index = current_id.indexOf(item);
if(index == -1){
delete_id.push(item);
} else {
existing_id.push(item);
}
}
for(let item of current_id){
let index = previous_id.indexOf(item);
if(index == -1){
new_id.push(item);
}
}
console.log(delete_id)
console.log(new_id)
console.log(existing_id)
答案 0 :(得分:1)
基本设置操作应该起作用:
// Copied directly from MDN
function intersection(setA, setB) {
var _intersection = new Set();
for (var elem of setB) {
if (setA.has(elem)) {
_intersection.add(elem);
}
}
return _intersection;
}
function difference(setA, setB) {
var _difference = new Set(setA);
for (var elem of setB) {
_difference.delete(elem);
}
return _difference;
}
let previous_id = ["5b7b5498ab3f510e307e7d04", "5b7ae97cc6d75e1331e28d9c", "5b7a0c207fab2722a2081caf"],
current_id = ["5b7b5498ab3f510e307e7d04", "5b83e3b4412f370bd7b9a05d"],
previous_set = new Set(previous_id),
current_set = new Set(current_id),
// perform set operations on the two sets
existing_ids = intersection(previous_set, current_set),
deleted_ids = difference(previous_set, current_set),
new_ids = difference(current_set, previous_set);
console.log("Existing ids: ", Array.from(existing_ids));
console.log("Deleted ids: ", Array.from(deleted_ids));
console.log("New ids: ", Array.from(new_ids));
集合操作比列表操作更有效,因此应在有意义的任何时候使用集合。
答案 1 :(得分:1)
我会在设置的数组之上构建数组操作。由于不应有重复项,因此这是内部计算的正确结构。我不知道为什么Set.prototype
至少没有union
,intersection
和difference
,但是自己编写它们是很简单的。
// Set operations
const intersection = (set1, set2) => new Set([...set1].filter(x => set2.has(x)))
const difference = (set1, set2) => new Set([...set1].filter(x => !set2.has(x)))
// Array operations, builtt using the set ones
// NB: Arrays are NOT Sets, and there is some information lost in the conversion.
// But Sets are the proper data structure for unordered collections of unique values.
const intersectionA = (arr1, arr2) => Array.from(intersection(new Set(arr1), new Set(arr2)))
const differenceA = (arr1, arr2) => Array.from(difference(new Set(arr1), new Set(arr2)))
// Main code
const breakdown = (prev, curr) => ({
delete_id: differenceA(prev, curr),
new_id: differenceA(curr, prev),
existing_id: intersectionA(prev, curr)
})
let previous_id = ["5b7b5498ab3f510e307e7d04", "5b7ae97cc6d75e1331e28d9c", "5b7a0c207fab2722a2081caf"];
let current_id = ["5b7b5498ab3f510e307e7d04", "5b83e3b4412f370bd7b9a05d"];
console.log(breakdown(previous_id, current_id))
如果您对多个循环的反对与代码膨胀有关,那么这可能会有所帮助。如果您认为多个循环是应用程序中的性能瓶颈(您已经测试过了吧?),那么这根本无济于事,因为它会针对所需的每个输出单独循环,并且在数组之间的转换上还有其他工作和集。但是如果这些引起应用程序的严重瓶颈,我会感到非常惊讶。