js 不定时更新数组问题
问题:往一个数组中push对象,对象的唯一标识为name,当push到某个对象时,发现数组中存在 name相等的对象,此时如何更新数组中name相同的对象为当前要push的对象,如果数组中的对象已经存在>6秒则删除此对象。
代码:
const objArray = [{name: 1, other: 2}, {name: 2, other: 2}];const addObj = {name: 2, other: 4}
const index = objArray.findIndex(i => i.name === addObj.name);
if(index > -1) {
objArray[index] = addObj;
} else {
objArray.push(addObj);
}
不定时向objArray push对象,name相等则更新且当前对象存在数组的时间重新计算,不相等就push,那么如果数组中的对象存在6秒且没有更新,怎么写逻辑从数组中删除此对象
回答:
这题肯定不能用数组遍历做。太恐怖了,建议你维护个额外队列,把搜索这块做成 n(1)
。
// 你维护的数据list1 = []
// 判断存在位置的数据
hash1 = {
// key 是name
// value 是下标
key: value
}
这样你做的时候只需要判断 hash 里面有没有就完事了,有的话就是更新。没有就是push并记录下标。
也不能说妥了,其实你可以在读的时候做,判断缓存过期就不读了。维护一个有序的队列。比如说最早的在最前面,定时做删除,这样就是 一个 while 判断。
list = [];list._push = list.push;
list._hash = {};
list.push = function(item){
let idx = this._hash[item.name];
console.log(item, idx, this.length)
if(idx === undefined){
this._hash[item.name] = this.length
this._push(item);
}else{
this[idx] = item;
}
}
list.push({name: 1, value: 0})
list.push({name: 2, value: 1})
list.push({name: 1, value: 2})
list.push({name: 3, value: 3})
console.log(list, list.length)
回答:
这个问题就是多定时器和单循环的选择问题了
1、多定时器,因为数组数量不定,多定时器会增加内存开销,可能会有内存泄漏的风险,所以不推荐
2、单循环,在循环中遍历数组从而更新数组,这里循环的间隔不宜过长,不然数组更新不及时,可以使用requestAnimationFrame,以下是实现:
let objArray;// 这是添加Object的方法,给每个object增加time属性,记录add的时间
function addObject(obj) {
obj.time = Date.now();
const index = objArray.findIndex(i => i.name === obj.name);
if (index > -1) {
objArray[index] = obj;
} else {
objArray.push(obj);
}
}
// 使用requestAnimationFrame不断遍历数组进行更新
function checkList() {
objArray = objArray.filter(obj => {
return Date.now() - obj.time < 6e3;
});
requestAnimationFrame(checkList);
}
// 启动遍历
checkList();
回答:
对于数据,想按 name
查找节点并替换之,可以用 findIndex
找到索引,再替换掉。如果数组中的数据较大,就不适合使用数据来遍历查找了,应该是使用 Map,不管是用 object map 还是用 Map 类都可以。
节点中可以保存一个时间数据,直接给节点这个数据,在加入的时候赋时间值就好。可以考虑使用 Proxy 自动注入 stamp。
而 6000 毫秒过期这个事情,不一定真的是要每 6 秒(或者更高频次)进行一次清理。只需要在使用数据的时候进行一次过滤就好。在缓冲区足够的情况下,每次使用数据的时候过滤出 6 秒内的数据就好。只有在达到一定时间(比如半分钟)或者一定空间的情况下,再触发清理。甚至如果使用的数据时只使用“单个”的情况下,都只需要把这个数据找出来判断是否过期就行,不需要过滤完了再来找。
回答:
其实从你的描述来说,这个问题可能还可以简化一下,因为无论name
对应对象是否存在,其实你都需要push
进去,因为需要更新时间,所以你其实可以考虑一个较长的先进先删的通道(实际上是有头部指针标记、尾部指针标记、搜索指针标记的 双向链表,或者环形数组),不停的向里面push
,但查找时从尾部开始查找(找到最新push
进去的值)。这样只需要提取值时看是否有效就好。
这样有一个好处就是,其实可以不主动删除,直到存满时,再触发一次删除超过6秒的(逆序搜索到第一个时间超过6秒的节点,头部指针直到其后即可)
其实要优化这个问题的解决方案,还需要题主真正给出这个数组完整的用途,因为数组用途(使用方法),对优化方向有特别大的影响。而不是简单的,靠题主现在简单的介绍(现在可能不完整、有些细节可能没有介绍到位)。
以上是 js 不定时更新数组问题 的全部内容, 来源链接: utcz.com/p/936799.html