不能单靠Set实现最近搜索历史,因其无法将已有元素移至末尾;应采用Set+数组双结构(或Map单结构)协同管理去重与顺序。

直接用 Set 无法保持插入顺序,所以不能单靠 Set 实现“最近搜索历史”——它需要去重(唯一性)+ 按时间倒序排列(最新在前)。核心思路是:用 Set 管理存在性,用数组(或双向链表)维护顺序,二者协同更新。
为什么不能只用 Set?
ES6 的 Set 确保元素唯一,但遍历时按插入顺序(现代引擎基本如此),看似可用。问题在于:它不支持“把已有元素移到末尾”这种操作。例如用户重复搜“React”,你得把它从中间移出、再加到末尾,而 Set 没有索引、无法定位和移动已有项。
推荐方案:Set + 数组双结构同步管理
用数组存储搜索词(保持顺序),用 Set 快速判断是否已存在。每次新增时,先查 Set,再操作数组,保证 O(1) 查重 + O(n) 数组更新(实际 n 很小,可接受)。
-
添加搜索词:若词已在 Set 中,先从数组中删除(
array.splice(array.indexOf(word), 1)),再push到末尾;否则直接push并add到 Set -
限制长度:每次添加后检查数组长度,超限时
shift()删除最旧项,并从 Set 中delete -
获取最近 N 条:直接取数组后 N 项(
array.slice(-N)),顺序天然就是“最新在前”
进阶优化:用 Map 替代双结构(更简洁)
Map 本身保留插入顺序,且支持 O(1) 查键、O(1) 删除任意键。可以把搜索词作为 key,value 可设为时间戳或仅用 true 占位:
- 新增时:
map.delete(word); map.set(word, true)—— 自动去重 + 移至末尾 - 取最近 N 条:
[...map.keys()].slice(-N).reverse()(因最新在末尾,需 reverse 才让最新在前) - 控制容量:
if (map.size > MAX) map.delete(map.keys().next().value)(删第一个,即最旧)
注意事项与边界处理
搜索词通常要标准化:trim 空格、忽略大小写(word.toLowerCase())、过滤空字符串。建议封装成函数,统一处理输入;另外,如果需要持久化(如 localStorage),只需序列化数组(JSON.stringify(array)),不必存 Set 或 Map。










