说我有一个函数,可以将字符列表收集到所有连续的相同字符的列表中:
[a, a, b, a, b, b, b, c, c, c, c] -> [[a, a], [b], [a], [b, b, b], [c, c, c, c]]
我在这里的解决方案是像这样手动填充ArrayList:
fun foo(chars: List<Char>): List<List<Char>> {
val result = arrayListOf<ArrayList<Char>>()
var part = arrayListOf(chars.first())
var cur = chars.first()
for (char in chars.drop(1)){
if (cur == char) part.add(char)
else {
cur = char
result.add(part)
part = arrayListOf(char)
}
}
if(part.isNotEmpty()) result.add(part)
return result
}
但是,这似乎太糟糕了,所以我认为必须有一种更好的方法来做到这一点。有什么想法吗?
答案 0 :(得分:2)
您可以使用groupBy
[功能] [1]:
val chars = listOf('a', 'a', 'b', 'a')
val result = chars.groupBy { it } // Map<Char,List<Char>> = ['a' to ['a','a'], 'b' to ['b']]
如果您之后想要列表列表,只需使用result.values
编辑
感谢指出,答案不应该包括所有的群体,而应该包括相应的群体。解决方案要更长一些:
val chars = listOf('a', 'a', 'b', 'a')
val result = chars.fold(mutableListOf<Char>() to mutableListOf<List<Char>>()) { (currentList, allLists), currentItem ->
if (currentList.isEmpty()) { // Applies only to the very first item
mutableListOf(currentItem) to allLists
} else {
if (currentItem == currentList.first()) { // same char
currentList.apply { add(currentItem) } to allLists
} else {
mutableListOf(currentItem) to allLists.apply { add(currentList) } // Next
}
}
}
.let { it.second.apply { add(it.first) } } //Convert to List<List<Char>> and add last remaining list
答案 1 :(得分:1)
作为一种选择,可以单行转换
fun main(args: Array<String>) {
val list = arrayListOf('a', 'a', 'b', 'a', 'b', 'b', 'b', 'c', 'c', 'c', 'c')
val result = "(\\w)\\1*".toRegex().findAll(list.joinToString("")).map { it.value.toCharArray() }.toList()
for (arr in result) {
print(arr.contentToString()) // prints [a, a][b][a][b, b, b][c, c, c, c]
}
}