5.3.8 分组操作符
groupBy(keySelector: (T) -> K): Map<K, List<T>>
将集合中的元素按照条件选择器keySelector
(是一个函数)分组,并返回Map。
代码示例:
>>> val words = listOf("a", "abc", "ab", "def", "abcd")
>>> val lengthGroup = words.groupBy { it.length }
>>> lengthGroup
{1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
```#### `groupBy(keySelector: (T) -> K, valueTransform: (T) -> V)`
分组函数还有一个是`groupBy(keySelector: (T) -> K, valueTransform: (T) -> V)`,根据条件选择器keySelector和转换函数valueTransform分组。
代码示例
```kotlin
>>> val programmer = listOf("K&R" to "C", "Bjar" to "C++", "Linus" to "C", "James" to "Java")
>>> programmer
[(K&R, C), (Bjar, C++), (Linus, C), (James, Java)]
>>> programmer.groupBy({it.second}, {it.first})
{C=[K&R, Linus], C++=[Bjar], Java=[James]}
这里涉及到一个二元组Pair 类,该类是Kotlin提供的用来处理二元数据组的。 可以理解成Map中的一个键值对,比如Pair(“key”,”value”) 等价于 “key” to “value”。
我们再通过下面的代码示例,来看一下这两个分组的区别:
>>> val words = listOf("a", "abc", "ab", "def", "abcd")
>>> words.groupBy( { it.length })
{1=[a], 3=[abc, def], 2=[ab], 4=[abcd]}
>>> words.groupBy( { it.length },{it.contains("b")})
{1=[false], 3=[true, false], 2=[true], 4=[true]}
我们可以看出,后者是在前者的基础上又映射了一次{it.contains("b")}
,把第2次映射的结果放到返回的Map中了。#### groupingBy(crossinline keySelector: (T) -> K): Grouping<T, K>
另外,我们还可以使用groupingBy(crossinline keySelector: (T) -> K): Grouping<T, K>
函数来创建一个Grouping
,然后调用计数函数eachCount
统计分组:
代码示例
>>> val words = "one two three four five six seven eight nine ten".split(' ')
>>> words.groupingBy({it.first()}).eachCount()
{o=1, t=3, f=2, s=2, e=1, n=1}
上面的例子是统计words列表的元素单词中首字母出现的频数。
其中,eachCount
函数定义如下:
@SinceKotlin("1.1")
@JvmVersion
public fun <T, K> Grouping<T, K>.eachCount(): Map<K, Int> =
// fold(0) { acc, e -> acc + 1 } optimized for boxing
foldTo( destination = mutableMapOf(),
initialValueSelector = { _, _ -> kotlin.jvm.internal.Ref.IntRef() },
operation = { _, acc, _ -> acc.apply { element += 1 } })
.mapValuesInPlace { it.value.element }
当前内容版权归 JackChan1999 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 JackChan1999 .