如何筛选出跨昨日今日含相似评论的同IssueId对象至新数组?
嘿,我来帮你理清楚这个问题的解决思路,其实分几步走就很清晰了~
核心思路拆解
我们的目标是找出同一issueId下,昨日和今日发布的、评论内容相似的对象对,所以可以拆成这几个关键步骤:
- 先按
issueId对原数组分组,这样我们能专注处理同一个issue下的所有记录 - 对每个分组,筛选出「昨日」和「今日」的对象集合
- 遍历两个集合,检查评论是否相似,匹配上的就组成对放入结果数组
假设你已经用moment获取了标准格式的昨日/今日日期(比如YYYY-MM-DD),原数组的对象结构大概是这样:
{ issueId: 'ISSUE-123', comment: '123123as...', date: '2024-05-20' // 存储记录的日期 }
方法一:ES6原生实现(无额外依赖)
纯原生JS就能搞定,代码逻辑清晰:
// 先定义好昨日和今日的日期(假设你已经用moment处理过) const today = moment().format('YYYY-MM-DD'); const yesterday = moment().subtract(1, 'day').format('YYYY-MM-DD'); const originalArray = [/* 你的原始对象数组 */]; // 1. 按issueId分组 const groupedByIssue = originalArray.reduce((acc, item) => { const key = item.issueId; if (!acc[key]) acc[key] = []; acc[key].push(item); return acc; }, {}); // 2. 自定义评论相似判断函数(你可以根据需求调整规则) // 示例规则:去掉末尾省略号后,前6个字符完全相同 const isCommentSimilar = (commentA, commentB) => { // 先清理评论内容,去掉末尾的省略号和空格 const cleanA = commentA.replace(/\.{3}$/, '').trim(); const cleanB = commentB.replace(/\.{3}$/, '').trim(); // 这里可以换成更复杂的规则,比如关键词匹配、字符串相似度算法等 return cleanA.slice(0, 6) === cleanB.slice(0, 6); }; // 3. 遍历分组,筛选匹配的对象对 const result = []; Object.values(groupedByIssue).forEach(group => { // 从分组里挑出今日和昨日的记录 const todayItems = group.filter(item => item.date === today); const yesterdayItems = group.filter(item => item.date === yesterday); // 两两匹配检查评论 todayItems.forEach(todayItem => { yesterdayItems.forEach(yesterdayItem => { if (isCommentSimilar(todayItem.comment, yesterdayItem.comment)) { // 按你需要的格式存储,这里用数组存昨日+今日对象 result.push([yesterdayItem, todayItem]); // 也可以改成对象形式:result.push({ yesterday: yesterdayItem, today: todayItem }) } }); }); }); console.log(result); // 最终的匹配结果数组
方法二:用Underscore.js简化代码
如果你习惯用Underscore,代码会更简洁,减少手动遍历的冗余:
const today = moment().format('YYYY-MM-DD'); const yesterday = moment().subtract(1, 'day').format('YYYY-MM-DD'); const originalArray = [/* 你的原始对象数组 */]; // 1. 按issueId分组(Underscore直接提供groupBy方法) const groupedByIssue = _.groupBy(originalArray, 'issueId'); // 2. 同样的评论相似判断函数 const isCommentSimilar = (commentA, commentB) => { const cleanA = commentA.replace(/\.{3}$/, '').trim(); const cleanB = commentB.replace(/\.{3}$/, '').trim(); return cleanA.slice(0, 6) === cleanB.slice(0, 6); }; // 3. 遍历分组筛选结果 const result = []; _.each(groupedByIssue, (group) => { const todayItems = _.filter(group, item => item.date === today); const yesterdayItems = _.filter(group, item => item.date === yesterday); _.forEach(todayItems, todayItem => { _.forEach(yesterdayItems, yesterdayItem => { if (isCommentSimilar(todayItem.comment, yesterdayItem.comment)) { result.push({ yesterday: yesterdayItem, today: todayItem }); } }); }); }); console.log(result);
关键注意点
- 评论相似规则:你可以完全自定义
isCommentSimilar的逻辑,比如用Levenshtein距离计算字符串相似度、判断是否包含相同关键词,或者匹配正则表达式,根据你的实际场景调整就行。 - 日期匹配:确保对象中的
date字段格式和moment生成的一致,如果是时间戳,记得用moment转成日期字符串再比较。 - 结果格式:你可以根据需求修改结果的存储形式,比如嵌套数组、对象包对象,都很灵活。
内容的提问来源于stack exchange,提问作者WannaBeBetter
相关产品推荐
相关产品推荐

