Перебор списка с помощью lambda forEach Kotlin

#android #lambda #kotlin

#Android #лямбда — выражение #kotlin #lambda

Вопрос:

У меня есть список из 30 случайных чисел, которые соответствуют 1 из 8 цветов, и мне нужно перебрать 8 цветов (или 30 чисел) и найти, сколько раз встречается каждый цвет. Мне нужно сделать это, используя лямбды и функциональное программирование, поэтому никаких традиционных циклов for.

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

iterator.forEach{

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

Проблема в настоящее время заключается в том, что мой вывод для count равен всего 50, а не конкретному количеству совпадений цвета.

Если я сделаю это вот так:

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

он выводит правильное число, но не с помощью цикла.

К чему это приводит:

 green count: 50 

red count: 50
  

что он должен выводить (например)

 green count:9

red count:3
  

Заранее спасибо

Ответ №1:

Добавьте именованный параметр в свой цикл forEach. Неявное имя «it» затеняется функцией count.

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

iterator.forEach { colour ->

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

Ответ №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}