场景:
地图可见区域房源数据,在拖动地图时需要知道哪些是已经有的房源,哪些是新加的房源,超出区域的房源需要删掉。
解决方案:
两个数组,需要找出第一个数组里面的重复值和非重复值。即一个数组保存上一次数据,另一个数组保留新数据。重复值保留,非重复值删除。
1.双重循环
var lastHouse = [];
filterHouse: function (houses) {
var remainsHourses = [],
newHourses = [];
for (var i = 0; i < houses.length; i ++) {
var isNewHouse = true;
for (var j = 0; j < lastHouse.length; j ++ ) {
if (houses[i].id === lastHouse[j].id) {
isNewHouse = false;
remainsHourses.push(lastHouse[j]);
break
}
}
if (isNewHouse) {
newHourses.push(houses[i])
}
}
lastHouse = remainsHourses.concat(newHourses)
return {
remainsHourses: remainsHourses,
newHourses: newHourses
}
}
但是用双重循环,所以这个算法的时间复杂度为O(N^2),对百级的数据还好,对于千级的数据可能压力就会很大。
2.使用Set
var lastHouse = new Set()
filterHouse: function (houses) {
var remainsHourses = [],
newHourses = [];
for (var i = houses.length - 1; i >= 0; i --) {
if (lastHouse.has(houses[i].id)) {
remainsHourses.push(houses[i])
} else {
newHourses.push(houses[i])
}
}
for (var i = 0; i < newHourses.length; i ++) {
lastHouse.add(newHourses[i].id)
}
return {
remainsHourses: remainsHourses,
newHourses: newHourses
}
}
使用Set可以减少一重循环,Set一般是使用红黑树实现的,即平衡二叉树,查找时间复杂度为O(longN),谷歌的V8Set是哈希实现的,时间复杂度为O(1),所以总体的时间复杂度降低了。
对上述代码还能用es6改写:
var lastHouse = new Set()
filterHouse: function (houses) {
var remainsHourses = [],
newHourses = [];
houses.map(house => lastHouse.has(house.id) ? remainsHourses.push(house) : newHourses.push(house))
newHourses.map(house => lastHouse.add(house.id))
return {
remainsHourses,
newHourses
}
}