修改原数组后,基于该数组生成的Map是否会自动同步更新?
问题根因
你当前逻辑失效有两个核心原因:
- 初始化Map时你传入的是空数组
array,生成的Map本身就是空的,调用map.get(随机数)返回的是undefined,和数值3比较时结果永远为false,所以判断条件从来不会触发 - 原生JS的普通数组和Map不存在自动同步机制,手动修改数组元素不会主动触发Map的统计逻辑更新
方案1:手动更新Map(最推荐)
不需要实现复杂的同步逻辑,每次给数组赋值后主动更新Map的计数即可,修改后代码如下:
var array = []; // 初始为空直接声明空Map即可,不需要调用reduce var map = new Map(); for (var i = 0; i < 24; i++) { var random = Math.floor(Math.random() * 10); // 取不到值的时候默认计数为0 var count = map.get(random) || 0; if (count < 3) { array[i] = random; // 赋值后手动更新Map计数 map.set(random, count + 1); } }
方案2:用Proxy实现数组和Map自动同步
如果你确实需要自动同步的能力,可以用Proxy代理数组,拦截所有会修改数组内容的操作,自动触发Map的计数更新:
// 封装创建同步数组和Map的方法 function createArrayWithSyncMap() { const map = new Map(); const array = new Proxy([], { set(target, prop, value) { // 只处理数组元素的赋值,跳过length等属性的修改 if (!isNaN(Number(prop))) { // 如果原位置有旧值,先把旧值的计数减1 const oldVal = target[prop]; if (oldVal !== undefined) { const oldCount = map.get(oldVal); map.set(oldVal, oldCount - 1); if (map.get(oldVal) === 0) map.delete(oldVal); } // 新值计数加1 const newCount = map.get(value) || 0; map.set(value, newCount + 1); } target[prop] = value; return true; } }); return { array, map }; } // 使用示例 const { array, map } = createArrayWithSyncMap(); for (var i = 0; i < 24; i++) { var random = Math.floor(Math.random() * 10); if ((map.get(random) || 0) < 3) { // 给数组赋值后Map会自动更新,不需要额外手动操作 array[i] = random; } }
注意:这种方案会拦截所有数组赋值操作,大量数组操作场景下性能会略低于手动更新方案,适合对同步要求高、数组操作频率不高的场景。
内容的提问来源于stack exchange,提问作者Laila
相关产品推荐
相关产品推荐

