我有一个数组arr,我要从中删除具有
的重复对象
_同样e_display_id
_和e_type
作为P
。
在这种情况下,我只想考虑带有status==='N'
的对象。
下面是输入数组arr:
let arr =
[ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" }
, { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" }
, { e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
, { e_type: "P", e_record_id: 420, e_display_id: "PE-14-911", status: "Y" }
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
];
我当前的实现方式:
我正在使用loadash方法将e_type
过滤为P
然后检查是否有重复的e_display_id
,
如果仅存在,则仅将具有status
的那个视为N
。
let clonedPursuits = [...arr];
let myarr = _.filter(clonedPursuits, x => x.e_type === 'P');
const counts = _.countBy(myarr, 'e_display_id');
clonedPursuits = _.filter(myarr, x => counts[x.e_display_id] > 1);
const uniqueAddresses = Array.from(new Set(clonedPursuits.map(a => a.e_display_id)))
.map(id => {
return clonedPursuits.find(a => a.e_display_id === id && a.status === "N");
});
console.log( uniqueAddresses );
预期输出:
[ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" }
, { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" }
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
];
当前输出:
[ { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N"}
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N"}
]
答案 0 :(得分:0)
我已经做到了:
const arr =
[ { e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" }
, { e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" }
, { e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
, { e_type: "P", e_record_id: 420, e_display_id: "PE-14-911", status: "Y" }
, { e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
, { e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
]
const res = arr.reduce((a,c,i,t)=>
{
if (c.e_type!=='P')
a.push({...c})
else
{
if (c.status==='N')
a.push({...c})
else if (!t.some(x=> x.e_type==='P' && x.e_display_id===c.e_display_id && x.status==='N' ))
a.push({...c})
}
return a
},[])
console.log( res )
console.log( ' --------- original array direct removing:-----------------')
// If you prefer to delete the elements directly without creating another array:
for(let i=arr.length;i--;)
{
let c = arr[i]
if (c.e_type!=='P') continue
if (c.status==='N') continue
if (!arr.some(x=> x.e_type==='P' && x.e_display_id===c.e_display_id && x.status==='N' )) continue
arr.splice(i,1)
}
console.log( arr )
.as-console-wrapper { max-height: 100% !important; top: 0; }
答案 1 :(得分:0)
我认为这应该为您做。该解决方案的优点在于,它最多只能(最多)两次通过项数组,这意味着它具有O(n)
的时间复杂度,因此非常高效。此解决方案的缺点是,它不保留项目的顺序,因此,如果顺序很重要,则需要重新排序它们,这使解决方案O(nlog(n))
。
此解决方案背后的想法是,将您知道的项目添加到项目列表的第一遍中,同时还要跟踪看到的e_display_id
及其状态。然后第二次遍历数据(反复查看已看到但未添加的内容),您将立即知道根据规则需要添加哪些内容。
let arr = [
{ e_type: "P", e_record_id: 33780, e_display_id: "EA-15-001", status: "Y" },
{ e_type: "P", e_record_id: 33744, e_display_id: "PE-14-016", status: "N" },
{ e_type: "P", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" },
{ e_type: "P", e_record_id: 420, e_display_id: "PE-14-911", status: "Y" },
{ e_type: "P", e_record_id: 421, e_display_id: "PE-14-911", status: "N" },
{ e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" },
{ e_type: "R", e_record_id: 33386, e_display_id: "PE-14-016", status: "Y" }
];
let seen = {};
let filtered = arr.reduce((res, curr) => {
let type = curr.e_type;
let status = curr.status;
let id = curr.e_display_id;
if (type !== "P") {
// if type is not "P", we add it unconditionally
res.push(curr);
}
else {
if (!seen[id]) { seen[id] = {}; }
if (!seen[id][status]) { seen[id][status] = []; }
// add to "seen" list for status "N" or "Y" for this e_display_id
// so we can decide later whether to keep it or throw it away
seen[id][status].push(curr);
}
return res;
}, [])
// add the e_type = "P" items in to final results based on e_display_id
let finalResults = filtered.concat(Object.values(seen).reduce((res, curr) => {
// keep Ns, regardless if there are multiples for that e_display_id
if (curr["N"]) { res.push(...curr["N"]); }
// if no Ns, keep Ys as long as no duplicates,
// meaning only 1 item in "seen" array for this e_display_id
else if (curr["Y"] && curr["Y"].length === 1) { res.push(...curr["Y"]); }
return res;
}, []))
console.log(finalResults);