Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Kotlin:将大列表转换为设置分区大小的子列表_Kotlin - Fatal编程技术网

Kotlin:将大列表转换为设置分区大小的子列表

Kotlin:将大列表转换为设置分区大小的子列表,kotlin,Kotlin,我正在寻找一个与之等效的函数,它可以将一个大的列表分成若干批进行处理。我确实看到了哪些可以被改编成类似的功能,但我想检查并确保我没有错过一个内置的或疯狂的简单替代方案,而不是自己的功能。注意:对于Kotlin 1.2及更新版本,请参阅标准库中的和功能。不需要定制解决方案 这里是一个延迟批处理扩展函数的实现,它将获取一个集合,或任何可以成为序列的对象,并返回一个序列列表的序列,最后一个是该大小或更小的值 将列表迭代为批的示例用法: myList.asSequence().batch(5).for

我正在寻找一个与之等效的函数,它可以将一个大的列表分成若干批进行处理。我确实看到了哪些可以被改编成类似的功能,但我想检查并确保我没有错过一个内置的或疯狂的简单替代方案,而不是自己的功能。

注意:对于Kotlin 1.2及更新版本,请参阅标准库中的和功能。不需要定制解决方案


这里是一个延迟批处理扩展函数的实现,它将获取一个集合,或任何可以成为
序列的对象,并返回一个
序列
列表
序列,最后一个是该大小或更小的值

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

myList.asSequence().batch(5).forEach { group ->
   // receive a Sequence of size 5 (or less for final)
}
列表
批次转换为
集合
的示例:

myList.asSequence().batch(5).map { it.toSet() }
请参阅下面的第一个测试用例,以显示给定特定输入的输出

函数的代码序列。批处理(groupSize)

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

private class BatchingSequence<T>(val source: Sequence<T>, val batchSize: Int) : Sequence<List<T>> {
    override fun iterator(): Iterator<List<T>> = object : AbstractIterator<List<T>>() {
        val iterate = if (batchSize > 0) source.iterator() else emptyList<T>().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<Int>, batchSize: Int, expectedGroups: Int) {
        var groupSeenCount = 0
        var itemsSeen = ArrayList<Int>()

        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<Int>().asSequence().batch(1).forEach { groupStream ->
            fail()
        }

    }
}
public-fun-Sequence.batch(n:Int):序列{
返回批处理顺序(此,n)
}
私有类BatchingSequence(val源:序列,val batchSize:Int):序列{
重写有趣的迭代器():迭代器=对象:AbstractIterator(){
val iterate=if(batchSize>0)source.iterator()else emptyList().iterator()
重写computeNext(){
if(iterate.hasNext())setNext(iterate.asSequence().take(batchSize.toList())
否则完成()
}
}
}
证明其有效的单元测试:

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

private class BatchingSequence<T>(val source: Sequence<T>, val batchSize: Int) : Sequence<List<T>> {
    override fun iterator(): Iterator<List<T>> = object : AbstractIterator<List<T>>() {
        val iterate = if (batchSize > 0) source.iterator() else emptyList<T>().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<Int>, batchSize: Int, expectedGroups: Int) {
        var groupSeenCount = 0
        var itemsSeen = ArrayList<Int>()

        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<Int>().asSequence().batch(1).forEach { groupStream ->
            fail()
        }

    }
}
class TestGroupingStream{
@Test fun TestConvertToListofGroup SwithOutConsumingGroup()测试乐趣{
val listOfGroups=listOf(1,2,3,4,5,6,7,8,9,10).asSequence().batch(2).toList()
assertEquals(5,组列表大小)
assertEquals(listOf(1,2),ListofGroup[0].toList())
assertEquals(listOf(3,4),ListofGroup[1].toList())
assertEquals(listOf(5,6),ListofGroup[2].toList())
assertEquals(listOf(7,8),ListofGroup[3].toList())
assertEquals(listOf(9,10),ListofGroup[4].toList())
}
@测试乐趣testSpecificCase(){
val originalStream=列表(1,2,3,4,5,6,7,8,9,10)
val results=originalStream.asSequence().batch(3).map{group->
toList()组
}托利斯先生()
assertEquals(列表(1,2,3),结果[0])
资产质量(列表(4,5,6),结果[1])
资产质量(列表(7,8,9),结果[2])
资产质量(列表(10),结果[3])
}
有趣的testStream(testList:List,batchSize:Int,expectedGroups:Int){
var groupSeenCount=0
var itemssen=ArrayList()
testList.asSequence().batch(batchSize).forEach{groupStream->
groupSeenCount++
groupStream.forEach{item->
项目SEEN.add(项目)
}
}
assertEquals(测试列表、项目SEN)
assertEquals(groupSeenCount、expectedGroups)
}
@测试组精确大小(){
测试流(列表(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15),5,3)
}
@测试乐趣组OddSize(){
测试流(列表(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)
}
@测试组小于BatchSize(){
testStream(listOf(1,2,3),5,1)
testStream(listOf(1),5,1)
}
@测试组大小1(){
testStream(listOf(1,2,3),1,3)
}
@测试乐趣组大小0(){
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)
}
@TestFunEmptySource(){
listOf().asSequence().batch(1).forEach{groupStream->
失败()
}
}
}

在Kotlin 1.2 M2及更高版本中,您可以使用和(请参阅)。请注意,也存在
序列
差异(请参阅)

对于1.2 M2之前的Kotlin版本,我建议使用
谷歌番石榴
(它使用):

如果您不熟悉,请参阅以了解更多详细信息

如果需要,您可以为其创建自己的Kotlin:

fun <T> List<T>.collate(size: Int): List<List<T>> = Lists.partition(this, size)

fun List.collate(大小:Int):序列{
需要(大小>0)
返回if(isEmpty()){
空序列
}否则{
(0..lastIndex/size).asSequence().map{
val fromIndex=it*大小
val toIndex=Math.min(fromIndex+size,this.size)
子列表(从索引到索引)
}
}
}

一个更简单/功能化的解决方案是

val items = (1..100).map { "foo_${it}" }

fun <T> Iterable<T>.batch(chunkSize: Int) =
   withIndex().                        // create index value pairs
   groupBy { it.index / chunkSize }.   // create grouping index
   map { it.value.map { it.value } }   // split into different partitions


items.batch(3)
val items=(1..100).map{“foo{it}”
有趣的Iterable.batch(chunkSize:Int)=
withIndex()。//创建索引值对
groupBy{it.index/chunkSize}.//创建分组索引
map{it.value.map{it.value}}//拆分为不同的分区
项目。批次(3)
注1:我个人更喜欢将
partition
作为这里的方法名,但Kotlin已经给出了一个谓词,将列表分成两部分


注2:Jayson的迭代器解决方案在大型集合中的扩展性可能比此解决方案更好。

不幸的是,目前还没有内置函数,而其他答案中基于函数和
序列的实现看起来不错,如果您只需要
列表的
列表
,我建议写一些难看的、命令式的、但性能良好的代码

这是我的最终结果:

fun <T> List<T>.batch(chunkSize: Int): List<List<T>> {
    if (chunkSize <= 0) {
        throw IllegalArgumentException("chunkSize must be greater than 0")
    }
    val capacity = (this.size + chunkSize - 1) / chunkSize
    val list = ArrayList<ArrayList<T>>(capacity)
    for (i in 0 until this.size) {
        if (i % chunkSize == 0) {
            list.add(ArrayList(chunkSize))
        }
        list.last().add(this.get(i))
    }
    return list
}
fun List.batch(chunkSize:Int):List{

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


#1.使用
#2.使用 虚拟阵列

使用:


显然,这可以使其不懒惰,例如映射到fun <T> List<T>.batch(chunkSize: Int): List<List<T>> { if (chunkSize <= 0) { throw IllegalArgumentException("chunkSize must be greater than 0") } val capacity = (this.size + chunkSize - 1) / chunkSize val list = ArrayList<ArrayList<T>>(capacity) for (i in 0 until this.size) { if (i % chunkSize == 0) { list.add(ArrayList(chunkSize)) } list.last().add(this.get(i)) } return list }
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]]
*/
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]]
*/
 for (i in 0..49){
             var  data="java"
            }
            array.add(data)
  var data=array?.chunked(15)