Kotlin вложил в циклы в asSequence - PullRequest
0 голосов
/ 02 апреля 2019

Я пытаюсь преобразовать свой вложенный цикл в asSequence в Котлине. Здесь моя цель - получить и обновить значение всего моего массива объектов из другого массива объектов с тем же ключом .

вложено в цикл:

val myFields = getMyFields()
val otherFields = getOtherFields()

for (myField in myFields) { // loop tru the my fields
     for (otherField in otherFields) { // find the same fields
          if (myField.key == otherField.key) { // if the same, update the value
              val updatedMyField = myField.copy(value = otherValue.value)

              myFields[myFields.indexOf(myField)] = updatedMyField // update my field value
              break
           }
      }
}

Что я пробовал:

val updatedMyFields = getMyFields().asSequence()
                    .map { myField ->
                        getOtherFields().asSequence()
                            .map { otherField ->
                                if (myField.key == otherField.key) {
                                    return@map otherField.value
                                } else {
                                    return@map ""
                                }
                            }
                            .filter { it?.isNotEmpty() == true }
                            .first()?.map { myField.copy(value = it.toString()) }
                    }
                    .toList()

но это не компилируется, так как вернет List<List<MyField>>.

Я просто ищу что-нибудь более чистое для этого.

Ответы [ 2 ]

2 голосов
/ 02 апреля 2019

Как отмечается в комментариях, это, вероятно, было бы гораздо более эффективным с Map.

(Точнее, решение карты заняло бы время, пропорциональное сумме длин спискав то время как вложенный цикл for занимает время, пропорциональное их продукту - который увеличивается намного быстрее.)

Вот один из способов сделать это:

val otherFields = getOtherFields().associate{ it.key to it.value }

val myFields = getMyFields().map {
    val otherValue = otherFields[it.key]
    if (otherValue != null) it.copy(value = otherValue) else it
}

Первыйстрока создает Map из ключей «других полей» к их значениям.Остальные затем используют его для создания нового списка из «моих полей», подставляя значения из «других полей», где они присутствуют.

Мне пришлось делать предположения о типах & c, так как код ввопрос неполный, но это должно сделать то же самое.Очевидно, что вы можете изменить способ объединения значений, внеся изменения в it.copy().

. Вероятно, в зависимости от окружающего кода могут быть еще более простые и эффективные способы.Если вы расширили его до Минимальный, завершенный и проверяемый пример - в частности, тот, который иллюстрирует, как вы уже используете Map, согласно вашему комментарию - мы могли бы предложить что-то лучшее.

0 голосов
/ 02 апреля 2019

Почему вы хотите использовать asSequence ()?Вы можете пойти примерно так:

 val myFields = getMyFields()
 val otherFields = getOtherFields()

        myFields.forEach{firstField ->
            otherFields.forEach{secondField ->
                if (firstField.key == secondField.key) {
                    myFields[myFields.indexOf(firstField)] = secondField.value
                }
            }
        }

Это выполнит ту же работу, что и ваш вложенный цикл, и его легче читать, понимать и поддерживать, чем вложенный asSequence ().

...