Outlook邮件分组后双层排序问题:组内与会话列表排序
解决Outlook会话分组后的双层排序问题
核心思路
要实现需求的两次排序,需要分两步处理:先对每个会话组内的邮件按时间从新到旧排序,再将所有会话组按组内最新邮件的时间从旧到新排序。由于原生对象无法直接排序,需要先将分组对象转换为数组处理,再根据需求决定是否转回对象。
实现代码
const cleanFolder = computed(() => { if (!currentFolder.value) return []; // 工具函数:将字符串日期转为可比较的Date对象 function parseReceivedDate(dateStr) { // 处理"07/11/1990 5:30PM"格式,转换为标准日期格式 const [month, day, yearTime] = dateStr.split('/'); const [year, time] = yearTime.split(' '); return new Date(`${year}-${month.padStart(2, '0')}-${day.padStart(2, '0')} ${time}`); } function groupBy(arr, property) { return arr.reduce((memo, x) => { const key = x[property]; if (!memo[key]) memo[key] = []; memo[key].push(x); // 组内排序:从新到旧(降序) memo[key].sort((a, b) => parseReceivedDate(b.received_date) - parseReceivedDate(a.received_date)); return memo; }, {}); } // 第一步:按conversation_id分组 const grouped = groupBy(currentFolder.value.emails, 'conversation_id'); // 第二步:将会话组按「组内最新邮件从旧到新」排序 // 转换为[key, 邮件数组]的数组格式进行排序 const sortedGroups = Object.entries(grouped).sort(([_, groupA], [__, groupB]) => { // 取每组首个元素(组内最新邮件)的日期做升序比较 return parseReceivedDate(groupA[0].received_date) - parseReceivedDate(groupB[0].received_date); }); // 可选:转回对象格式(ES6+会保留插入顺序) // const sortedGroupedObject = Object.fromEntries(sortedGroups); // 推荐返回数组格式,更方便渲染遍历 return sortedGroups; });
逻辑拆解
- 日期转换:将字符串格式的
received_date转为Date对象,避免直接比较字符串导致的排序错误。 - 组内排序:在分组的
reduce过程中,每次添加新邮件后对当前组数组做降序排序,确保最新邮件排在组内首位。 - 会话整体排序:把分组对象转为
[会话ID, 邮件数组]的数组,通过每组的首个元素(组内最新邮件)的日期做升序排序,实现会话从旧到新的排列。
渲染示例(Vue模板)
如果返回的是sortedGroups数组,可直接遍历渲染:
<div v-for="[convId, emails] in cleanFolder" :key="convId" class="conversation-group"> <div class="conversation-header"> <span>会话ID: {{ convId }}</span> <span>最新邮件时间: {{ emails[0].received_date }}</span> </div> <div v-for="email in emails" :key="email.id" class="email-item"> <p>发件人: {{ email.from }}</p> <p>接收时间: {{ email.received_date }}</p> </div> </div>
内容的提问来源于stack exchange,提问作者Qiuzman
相关产品推荐
相关产品推荐

