• 主页
  • 归档
  • 分类
  • 照片墙
所有文章 友情链接 关于我

  • 主页
  • 归档
  • 分类
  • 照片墙
  1. 1. 引入二分法查找
  2. 2. 删除仓库内的文件

博客图片迁移-后续

2019-04-23 19:13:17
总字数 756
预计阅读时间 3 分钟

本着不折腾不舒服的原则, 之前的图片迁移与构建时的自动同步虽然已经实现
但是仍有很多可以改进的地方

引入二分法查找

在执行本地文件列表与仓库内的文件列表比对的过程中
直接逐个比对找差异的复杂度高达O(n²)
何况还考虑之后要把本地没有, 但仓库里有的文件删除
这个执行时间太过漫长

所以考虑对文件列表排序后采用二分法查找
先写个二分法查找的js实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
/**
* 二分法查找
* @param {Array} arr 执行查找的数组
* @param {Object} target 要找到的目标元素
* @param {String} key 数组元素上的键
* @param {Number} start 查找的范围 起点
* @param {Number} end 查找的范围 终点
*/
function _binarySearch(arr, target, key, start, end) {
if(!Array.isArray(arr) || !arr.length) {
return -1
}
if(start >= end) {
return arr[start][key] === target ? start : -1
}
let index = Math.ceil((start + end)/2)
if(arr[index][key] === target) {
return index
} else if(arr[index][key] > target) {
return _binarySearch(arr, target, key, start, index-1)
} else {
return _binarySearch(arr, target, key, index+1, end)
}
}

二分法查找既可以使用递归方式实现, 也可以用循环实现

使用二分法查找需要保证数组是有序的
虽然现在看起来接口返回的数据本身就是有序, 但是还是执行一下排序保证不会出错
先使用Array.prototype.sort方法, 并指定排序规则进行排序
之后考虑更换为原数组基本有序的情况下, 更为高效的插入排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
let storageItems = ret.items.filter((item) => {
return /^images.+?\.(png|jpe?g|gif)$/.test(item.key)
}).sort((item1, item2) => {
if(item1.key > item2.key) {
return 1
} else if(item1.key < item2.key) {
return -1
}
return 0
})
// 待上传的文件列表
let pendingUploadFiles = imagesList.filter(item => {
let index = _binarySearch(storageItems, item.name, 'key', 0, storageItems.length-1)
if(index === -1) {
// 文件名不存在, 代表是新文件
item.type = 'new'
return true
} else if(storageItems[index].eTag !== item.md5) {
// 文件名存在, 但是hash值不同, 代表有变化
item.type = 'change'
return true
}
return false
})

整体来看效率提升不少

删除仓库内的文件

要找出本地不存在但是仓库内存在的文件, 调用删除文件的接口进行删除
方法基本雷同, 甚至简单很多
当然 imagesList 也需要是有序的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// 待删除的文件列表( 仓库中存在, 本地不存在 )
let pendingDeleteFiles = storageItems.filter(item => {
return _binarySearch(imagesList, item.key, 'name', 0, imagesList.length-1) === -1
})
_deleteObjects(pendingDeleteFiles.map(item => item.key))
/**
* 批量删除文件
* @param {Array} fileNamesList 文件名数组
*/
function _deleteObjects(fileNamesList) {
if(!Array.isArray(fileNamesList) || !fileNamesList.length) return

client.deleteMultiObject({
objectKeys: fileNamesList
}).then(err => {
console.log('===> 文件删除成功')
fileNamesList.forEach(item => console.log(item))
})
}

为了节约接口的调用次数, 还是选择批量删除的接口了

  • nodejs
  • 前端杂烩

扫一扫,分享到微信

webpack4升级踩坑
1.2、linux常用命令与技巧(2) 
© 2024 夏夜梦星辰
鲁ICP备19028444号
Power By Hexo
  • 所有文章
  • 友情链接
  • 关于我
{{searchItem.query}}
标签: 分类:
  • maven
  • 持续集成
  • JMS
  • 线程
  • JavaScript
  • ECMAScript6
  • 单元测试
  • Promise
  • Web Worker
  • 函数
  • prototype
  • 模块化
  • 正则表达式
  • 数据库
  • MongoDB
  • 索引
  • 集群
  • 全文检索
  • flutter
  • dart
  • git
  • 版本控制
  • linux
  • shell
  • docker
  • nginx
  • jenkins
  • opencv
  • vim
  • react
  • react native
  • 前端
  • css
  • HTML5
  • Hexo
  • sass
  • Three.js
  • TypeScript
  • Vue
  • 组件化
  • base64
  • webpack
  • nodejs
  • gulp
  • TensorFlow
  • 机器学习
  • 算法
  • 动态规划
  • 数据结构
  • Java
  • JavaScript
  • MongoDB
  • flutter
  • Git
  • linux
  • react
  • 前端杂烩
  • 男生女生
  • 算法
  • 十年饮冰,难凉热血
  • †少女癌†
  • 猫与向日葵
  • coderfun
  • JENKINS
  • API管理后台
愿你最终能接纳每一面每一种的自己
独自活着便是团圆