首页 > 解决方案 > 有没有一种更有效的方法可以以某种方式将项目列表映射到对列表?

问题描述

源数据:数组<文件>

目标返回数据: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)

标签: kotlincollections

解决方案


你可以先插入你需要的空值,这样你就可以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) }

推荐阅读