当前位置:  开发笔记 > 开发工具 > 正文

Kotlin:将大型List转换为set partition size的子列表

如何解决《Kotlin:将大型List转换为setpartitionsize的子列表》经验,为你挑选了2个好方法。

我正在寻找一个与Groovy的collat​​e相当的函数,它将大型List分成批处理.我确实看到subList哪些可以改编成类似的功能,但想检查并确保我没有错过内置或疯狂的简单替代滚动我自己.



1> Imanou Petit..:

使用Kotlin 1.3,根据您的需要,您可以选择以下方法之一来解决您的问题.


#1.运用chunked
fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.chunked(2)
    //val newList = list.chunked(size = 2) // also works
    print(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/

#2.运用windowed
fun main() {
    val list = listOf(2, 4, 3, 10, 8, 7, 9)
    val newList = list.windowed(2, 2, true)
    //val newList = list.windowed(size = 2, step = 2, partialWindows = true) // also works
    println(newList)
}

/*
prints:
[[2, 4], [3, 10], [8, 7], [9]]
*/



2> Jayson Minar..:

注意: 对于Kotlin 1.2及更高版本,请参阅标准库中的chunkedwindowed现在的功能.无需自定义解决方案.


这是一个懒惰的配料扩展功能,这将需要一个集合,或任何可以成为一个的实现Sequence和返回SequenceList每一个尺寸的,随着最后一个是该尺寸或更小.

将列表作为批处理迭代的示例用法:

myList.asSequence().batch(5).forEach { group ->
   // receive a Sequence of size 5 (or less for final)
}

将批次转换ListSet:

myList.asSequence().batch(5).map { it.toSet() }

请参阅下面的第一个测试用例,以显示给定特定输入的输出.

功能代码Sequence.batch(groupSize):

public fun  Sequence.batch(n: Int): Sequence> {
    return BatchingSequence(this, n)
}

private class BatchingSequence(val source: Sequence, val batchSize: Int) : Sequence> {
    override fun iterator(): Iterator> = object : AbstractIterator>() {
        val iterate = if (batchSize > 0) source.iterator() else emptyList().iterator()
        override fun computeNext() {
            if (iterate.hasNext()) setNext(iterate.asSequence().take(batchSize).toList())
            else done() 
        }
    }
}

单元测试证明它有效:

class TestGroupingStream {

    @Test fun testConvertToListOfGroupsWithoutConsumingGroup() {
        val listOfGroups = listOf(1, 2, 3, 4, 5, 6, 7, 8, 9, 10).asSequence().batch(2).toList()
        assertEquals(5, listOfGroups.size)
        assertEquals(listOf(1,2), listOfGroups[0].toList())
        assertEquals(listOf(3,4), listOfGroups[1].toList())
        assertEquals(listOf(5,6), listOfGroups[2].toList())
        assertEquals(listOf(7,8), listOfGroups[3].toList())
        assertEquals(listOf(9,10), listOfGroups[4].toList())
    }

    @Test fun testSpecificCase() {
        val originalStream = listOf(1,2,3,4,5,6,7,8,9,10)

        val results = originalStream.asSequence().batch(3).map { group ->
            group.toList()
        }.toList()

        assertEquals(listOf(1,2,3), results[0])
        assertEquals(listOf(4,5,6), results[1])
        assertEquals(listOf(7,8,9), results[2])
        assertEquals(listOf(10), results[3])
    }


    fun testStream(testList: List, batchSize: Int, expectedGroups: Int) {
        var groupSeenCount = 0
        var itemsSeen = ArrayList()

        testList.asSequence().batch(batchSize).forEach { groupStream ->
            groupSeenCount++
            groupStream.forEach { item ->
                itemsSeen.add(item)
            }
        }

        assertEquals(testList, itemsSeen)
        assertEquals(groupSeenCount, expectedGroups)
    }

    @Test fun groupsOfExactSize() {
        testStream(listOf(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15), 5, 3)
    }

    @Test fun groupsOfOddSize() {
        testStream(listOf(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18), 5, 4)
        testStream(listOf(1,2,3,4), 3, 2)
    }

    @Test fun groupsOfLessThanBatchSize() {
        testStream(listOf(1,2,3), 5, 1)
        testStream(listOf(1), 5, 1)
    }

    @Test fun groupsOfSize1() {
        testStream(listOf(1,2,3), 1, 3)
    }

    @Test fun groupsOfSize0() {
        val testList = listOf(1,2,3)

        val groupCountZero =   testList.asSequence().batch(0).toList().size
        assertEquals(0, groupCountZero)

        val groupCountNeg =  testList.asSequence().batch(-1).toList().size
        assertEquals(0, groupCountNeg)

    }

    @Test fun emptySource() {
        listOf().asSequence().batch(1).forEach { groupStream ->
            fail()
        }

    }
}


仅供参考:我认为你的'批次'代码中有一个错误.以下内容卡在无限循环`listOf(1,2,3,4,5,6,7,8,9,10).asSequence().batch(2).toList()`中.
尼斯.这使得代码也更简单.+1
推荐阅读
360691894_8a5c48
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有