如何通过导入的CSV邮件列表过滤对象数组?
问题描述
我有一个包含大量条目的对象数组,结构如下:
[ { owningrep: "Some name", id: 1, emails: "email@address.com;shane@emails.com" }, { owningrep: "Other name", id: 2, emails: "me@emailstuff.com" } ]
同时我有一个从CSV导入的邮箱数组:
["crona.audreanne@denesik.com", "minerva.leannon@pfannerstill.info", "barton.eloise@yahoo.com", "rachelle.rau@hotmail.com", "ihaley@morar.com", "ggleichner@kirlin.info", "keely.ledner@yahoo.com", "jerel05@yahoo.com", "eleonore35@murphy.info", "ivory56@hotmail.com", "email@address.com"]
需要过滤对象数组,只保留emails字段中不包含该邮箱数组内任意邮箱的对象。注意部分对象的emails字段是单个邮箱,部分是分号分隔的多个邮箱。之前直接用includes方法只能筛选少量条目,无法满足需求。
解决方案
核心思路是先把邮箱数组转成查询效率更高的Set,再对每个对象的emails字段拆分、清洗后,检查是否有匹配的邮箱,仅保留完全无匹配的对象。
步骤1:将邮箱数组转为Set(提升查询性能)
const exclusionEmailsSet = new Set(exclusionCSV.value);
用Set的has方法比数组includes快得多,尤其当邮箱数量很大时效果明显。
步骤2:过滤对象数组
遍历每个对象,拆分emails字段为单个邮箱列表,检查是否有任意邮箱在Set中:
const filteredData = data.filter(item => { // 拆分分号分隔的邮箱,同时去除前后空格(处理可能的格式问题) const itemEmails = item.emails.split(';').map(email => email.trim()); // 检查是否有任何一个邮箱在排除列表中 const hasExcludedEmail = itemEmails.some(email => exclusionEmailsSet.has(email)); // 只保留没有匹配排除邮箱的对象 return !hasExcludedEmail; });
结合你现有代码的完整示例
如果要结合你之前的inclusionsList处理逻辑,代码可以写成:
// 先处理包含列表筛选 const inc = inclusionsList.value.length > 0 && inclusionsList.value[0] !== 0 ? formatDataAsArray(data).filter(d => _.includes(inclusionsList.value, d.id)) : data; // 处理邮箱排除筛选 const exclusionEmailsSet = new Set(exclusionCSV.value); const fromCSV = formatDataAsArray(inc).filter(item => { const itemEmails = item.emails.split(';').map(email => email.trim()); return !itemEmails.some(email => exclusionEmailsSet.has(email)); });
结果验证
用你提供的测试数据,过滤后只会保留id:2的对象,因为id:1的emails里包含email@address.com,这个邮箱在排除数组中。
内容的提问来源于stack exchange,提问作者Shane Dalton Gray
相关产品推荐
相关产品推荐

