用lambda遍历列表for每个Kotlin

时间:2019-03-13 00:14:07

标签: android lambda kotlin

我有30个随机数字的列表,它们对应8种颜色中的1种,我需要遍历8种颜色(或30种数字),并找出每种颜色出现的次数。我需要使用lambda和函数编程来执行此操作,因此没有传统的for循环。

val iterator = colours.toList().iterator()

iterator.forEach{

    println("$it count: " + (numbers
            .map{a -> colours[a]}
            .count{it == ("$it")}))
}

当前的问题是我的计数输出仅为50,而不是发生颜色的特定次数。

如果我这样做:

println("Red count:" +    (numbers
        .map{a -> colours[a]}
        .count{it ==  ("red")}))

它输出正确的数字,但不带循环。

输出内容:

green count: 50 

red count: 50

它应该输出什么(例如)

green count:9

red count:3

预先感谢

2 个答案:

答案 0 :(得分:2)

为您的forEach循环添加一个命名参数。隐式名称“ it”正被count函数遮盖。

val iterator = colours.toList().iterator()

iterator.forEach { colour ->

    println("$colour count: " + (numbers
        .map{a -> colours[a]}
        .count{it == ("$colour")}))
}

答案 1 :(得分:2)

您实际上不需要在这里进行嵌套迭代。目前您的工作效率为O(n ^ 2),因为您必须为每个元素遍历一次列表。由于您知道自己正在使用少量潜在值,因此您可以按值对它们进行分组,然后将这些值映射到结果列表的大小,即

val colourNames = listOf("red", "green", "blue", "yellow", "orange", "indigo", "violet", "black")

// Generates 30 random numbers between 0 and 8 (exclusive)
val randomColours = (0 until 30).map { (0 until colourNames.size).random() }

val result = randomColours
  .groupBy { color -> colourNames[color] } // outputs a Map<String, List<Int>>
  .mapValues { (color, colorCountList) -> colorCountList.size } // Map<String, Int>

println(result) // {yellow=4, orange=4, red=5, indigo=3, blue=8, green=2, violet=2, black=2}