Kotlin 在多个索引处将 Arraylist 拆分为多个部分
Posted
技术标签:
【中文标题】Kotlin 在多个索引处将 Arraylist 拆分为多个部分【英文标题】:Kotlin splitting an Arraylist into parts at more than one Index 【发布时间】:2019-04-28 17:14:40 【问题描述】:假设我有一个 Arraylist
fun main() var myarrayList= ArrayList<String>() myarrayList.add("+23") myarrayList.add("-25") myarrayList.add("+125") myarrayList.add("+455") myarrayList.add("") myarrayList.add("*230") myarrayList.add("-293") myarrayList.add("/6") myarrayList.add("") myarrayList.add("+293") myarrayList.add("") myarrayList.add("+21") for (index in 0..myarrayList.size-1) print (index) print (" = ") print (myarrayList.get(index)) print ("\n")
我想在 value = "" 的每个索引处将其拆分为较小的 Arraylist。我知道我可以使用 indexOf() 和 lastIndexOf 对其进行切片,但我只能获得 2 个切片。我需要拆分成多个数组
【问题讨论】:
【参考方案1】:你绝对可以在这里使用arrayList的.sublist函数:
fun subList(fromIndex: Int, toIndex: Int): MutableList<E>
https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/-array-list/sub-list.html
【讨论】:
我实际上已经用一个粗略的子列表版本来管理它,但它非常混乱。我认为可能有更清洁的方法。顺便说一句,您的回复,【参考方案2】:我无法想象没有更简单的方法可以做到这一点......实际上有很多方法可以解决它,但都有一个或另一个“缺陷”(例如,你需要添加一些前面或末尾的索引...或者您需要注意不要丢失最后一个条目,因为没有最终的""
等)。如果您一开始就不需要列表列表,那么它可以很简单:
myarrayList.joinToString("")
if (it == "") "\n" else it
它基本上只返回一个String
,如下所示:
+23-25+125+455
*230-293/6
+293
+21
也许这给了你一个提示,joinToString
可能已经有什么其他可能...现在仍在使用 joinToString
但只是相应地拆分它(显然是一种解决方法):
myarrayList.joinToString("|")
if (it == "") "FORM_END" else it
.splitToSequence("|FORM_END|") // use split if List<*> is ok for you
.map
it.splitToSequence("|") // use split if *<List<String>> is ok for you
这现在基本上会给你一个序列序列。添加.map it.toList() .forEach(::println)
将得到以下结果:
[+23, -25, +125, +455]
[*230, -293, /6]
[+293]
[+21]
另一种方法,不使用joinToString
-workaround,而是使用mapIndexedNotNull
和zipWithNext
,其打印结果与以前相同:
myarrayList.mapIndexedNotNull i, s -> i.takeIf s == ""
.let
listOf(-1) + it + myarrayList.size // ugly, but we need beginning and end too, not only the delimiting indices
.asSequence()
.zipWithNext from, upto -> myarrayList.subList(from + 1, upto)
.forEach(::println)
您也可以使用fold
构建一些东西...但请务必同时收集列表的最后一个条目;-)
【讨论】:
感谢 Roland 非常明确的回答。我曾考虑过使用 JoinToString,我认为这可能是最干净的方法。在上面的示例中,我实际上并没有只使用单个数字。它是一种带有运行列表的计算器应用程序,就像带有纸卷的旧式桌面一样。 Arraylist 中的每一行将代表计算中的一行。一世。 e 一个数据类rowItem(lineNos, value, note) 好吧...可能是最易读的,但如果您首先不需要连接字符串,也是一种解决方法;-)【参考方案3】:我一直在寻找同样的东西,最终我为List
创建了自己的扩展函数。
fun <E> List<E>.split(separator: E): List<List<E>> =
mutableListOf<List<E>>().also result ->
var end = -1
var remaining = this
while (end < remaining.size)
remaining = remaining.drop(end + 1)
end = remaining.indexOf(separator).let
if (it == -1) remaining.size else it
result.add(remaining.subList(0, end))
【讨论】:
这应该是一个可以接受的答案。我添加了一个可以为空的分隔符:fun您可以使用集合函数的组合来解决您的问题。 首先你应该找到空字符串的索引(https://kotlinlang.org/api/latest/jvm/stdlib/kotlin.collections/map-indexed-not-null.html):
val splitPoints =
myarrayList.mapIndexedNotNull() idx, str -> if (str.isEmpty()) idx else null
接下来您可以使用windowed
从列表中连续获取两个项目。要获取列表的第一部分和最后一部分,您需要添加 -1 和 ArrayList
的大小。现在您可以使用sublist
并提取各个部分:
val splittedList =
(listOf(-1) + splitPoints + myarrayList.size)
.windowed(2, 1)
.map (start, end) -> myarrayList.subList(start + 1, end)
【讨论】:
【参考方案5】:我对 Kotlin /Anko 很陌生,并意识到您的答案涉及 RXKotlin。我从来没有听说过windowed,但查了一下。它要学习的更多。但是,我已经能够使用以下代码实现相同的目的。非常感谢大家的帮助
有趣的 main()
var myarrayList= ArrayList<String>()
var emptyIndexes= ArrayList<Int>()
emptyIndexes.add(0)
myarrayList.add("+23")
myarrayList.add("-25")
myarrayList.add("+125")
myarrayList.add("+455")
myarrayList.add("")
myarrayList.add("*230")
myarrayList.add("-293")
myarrayList.add("")
myarrayList.add("+293")
myarrayList.add("")
myarrayList.add("+21")
for (index in 0..myarrayList.size-1)
print (index)
print (" = ")
print (myarrayList.get(index))
print ("\n")
///find empty index
if (myarrayList.get(index)=="")
emptyIndexes.add(index)
emptyIndexes.add(myarrayList.size)
print("\n")
for (item in emptyIndexes)
print ("empty index "+ item +" ")
for (index in 0..emptyIndexes.size-1)
//println ("start index " +index)
if (index==emptyIndexes.size-1)break
//println ("end index "+ (index+1) )
// print("\n\nemptyIndixes size)"+ emptyIndexes.size +"\n\n")
var subCals=myarrayList.subList(emptyIndexes[index],emptyIndexes[(index+1)])
//println (subCals )
var stToCal=""
for (items in subCals)
stToCal=stToCal+items.toString()
【讨论】:
以上是关于Kotlin 在多个索引处将 Arraylist 拆分为多个部分的主要内容,如果未能解决你的问题,请参考以下文章