背景
在解决http://jira.iguming.net:8080/browse/XSWT-1422问题的时候,因为基本上所有读的接口都存在延迟的情况,所以判断有无更新不应该只是判断长度的更新。如果是配置角色,此时更新前后的数组长度不变,此时需要准确的检测更新机制。
思路
首次尝试:遍历+JSON.stringify
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| export const compareArraySame = (arr1, arr2) => { if (!arr1) arr1 = []; if (!arr2) arr2 = []; return ( arr1.length === arr2.length && arr1.every((item1) => arr2.map((item2) => JSON.stringify(item2)).includes(JSON.stringify(item1)) ) && arr2.every((item2) => arr1.map((item1) => JSON.stringify(item1)).includes(JSON.stringify(item2)) ) ); };
|
缺点:
- 性能低:时间复杂度$O(N^3)$(every, map, includes, &&)
- 不一定准确:JSON.stringify如何处理的对象顺序不一致,就不准确
提取相同key,排序后join比对
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const compareArraySame = (arr1, arr2) => { if (!arr1) arr1 = []; if (!arr2) arr2 = [];
const comp1 = arr1.map(item=>[item.id+item.name+item.role]); const comp2 = arr2.map(item=>[item.id+item.name+item.role]);
comp1.sort() comp2.sort()
return ( arr1.length === arr2.length && comp1.join('-') === comp2.join('-') ); };
|
分析
对于本次需求来讲,会变化的除了长度外,具体字设计到的字段只有2个:name和role。所以可以把对象数组的这两个字段拼出来,然后排序合并比对。此方法有两个注意点:
- 排序:因为修改角色后,数字可能会重新按照首字母排序
- 拼接的时候,得加上id表标识
时间复杂度
map —> O(N), sort —> O(NlognN, join —> O(N)
所以时间复杂度为O(2N+2NlogN+2*N)=O(NlogN)
缺点
方法不具有通用性
总结
第二种方法性能更好一点。值得注意的是,如果对性能要求很高,命令式变成比声明式编程会好一点.
参考资料
How To Calculate Time Complexity With Big O Notation
Big O Cheat Sheet – Time Complexity Chart
Performance of JavaScript .forEach, .map and .reduce vs for and for..of
模板—【🌀🌀🌀TODO】 (1)