kotlin - 有没有一种更有效的方法可以以某种方式将项目列表映射到对列表?
问题描述
源数据:数组<文件>
目标返回数据:List<Pair<File,File>>
源数据 (Array<File>) 包含一本书的 jpeg 列表,格式为 (Scan0001.jpg, Scan0002.jpg, ..., Scan000n.jpg)。第一个文件 (Scan0001.jpg) 始终是书籍的封面,最后一个文件 (Scan000n.jpg) 始终是书籍的封底。以下代码片段中的变量 files 是一个 Array<File!>,仅包含 Scanxxxx.jpg 形式的 jpeg 文件。
我想使用以下规则创建页面文件对:
1) 封面(正面、背面)应始终为 Pair<File,null> (文件分别为 Scan0001.jpg、Scan000n.jpg)
2)如果非封面页不均匀(意味着最后一页没有一对)它应该是 Pair<File,null> (文件为 Scan000n-1.jpg)
3) 封面始终是第一个文件对,封底始终是最后一个文件对
以下代码有效,但我觉得在更高效或更简洁的代码方面还有改进的空间
val files = selectedFolder.listFiles()
val preliminaryResult = files.toMutableList()
val result = mutableListOf<Pair<File?,File?>>()
result.add(Pair(preliminaryResult.first(),null))
preliminaryResult.removeAt(0)
result.add(Pair(preliminaryResult.last(),null))
preliminaryResult.removeAt(preliminaryResult.size-1)
result.addAll(preliminaryResult.map{
if(preliminaryResult.indexOf(it) % 2 == 0) {
Pair(it,preliminaryResult.getOrNull(preliminaryResult.indexOf(it)+1))
} else {
Pair(null,null)
}
})
result.removeAll{
it == Pair(null,null)
}
result.add(result[1])
result.removeAt(1)
解决方案
你可以先插入你需要的空值,这样你就可以zipWithNext
不间断地使用。
val result = selectedFolder.listFiles().toMutableList<File?>().apply {
add(1, null) // for front cover
if (0 == size % 2)
add(size - 1, null) // for odd inner last page
add(null) // for back cover
}.zipWithNext()
.run { slice(indices step 2) }
推荐阅读
- python - ModuleNotFoundError:没有名为 msg1 的模块(在带有 python 2.7.6 的 ubuntu 中没有显示任何错误)
- c# - .netcore EF linq - 这是一个错误吗?非常奇怪的行为
- ibm-cloud - Node-Red 应用程序再次询问“欢迎使用您的新 Node-RED 实例”
- javascript - TYPO3 前端:未找到表单操作结果页面
- java - 如何参考 TestNG 从 POM.XML 运行特定的 Java 类
- debugging - NuGet/MyGet 调试抛出未找到源代码错误
- sql - 每组记录只显示一次值
- git - 从现有的 Git 存储库中进行稀疏签出?
- jquery - 选择所有在 webgrid Jquery 和 ASP.net MVC 中不起作用的复选框
- jenkins - 无法启动 Windows 从代理 (Jenkins)