0

I'm trying to convert my nested for loop to asSequence in Kotlin. Here, my goal is to get and update the value of all my object array from another object array with the same key.

nested for loop:

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
           }
      }
}

What I've tried:

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()

but this does not compile as it will return List<List<MyField>>.

I'm just looking for something much cleaner for this.

4
  • Don't you think you should just remove the very last .toList()? Commented Apr 2, 2019 at 2:46
  • sorry just to add, I also don't think my solution is that much clean, maybe if there's any suggestion on how to do it in a cleaner way. Commented Apr 2, 2019 at 2:48
  • also shouldn't you be using a Map instead of a list? Commented Apr 2, 2019 at 5:03
  • Yes I do use a Map to swap value via key easily. I'm trying to look for a cleaner approach in my code above (nested for loop). Commented Apr 2, 2019 at 5:30

2 Answers 2

3

As comments suggest, this would probably be much more efficient with a Map.

(More precisely, a map solution would take time proportional to the sum of the list lengths, while the nested for loop takes time proportional to their product — which gets bigger much faster.)

Here's one way of doing that:

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
}

The first line creates a Map from the ‘other fields’ keys to their values.  The rest then uses it to create a new list from ‘my fields’, substituting the values from the ‘other fields’ where present.

I've had to make assumptions about the types &c, since the code in the question is incomplete, but this should do the same.  Obviously, you can change how it merges the values by amending the it.copy().

There are likely to be even simpler and more efficient ways, depending on the surrounding code.  If you expanded it into a Minimal, Complete, and Verifiable Example — in particular, one that illustrates how you already use a Map, as per your comment — we might be able to suggest something better.

Sign up to request clarification or add additional context in comments.

1 Comment

This is what I'm looking for, thanks also for the explanation, I'll just adjust this according to my actual needs :)
0

Why do you want to use asSequence() ? You can go for something like that:

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

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

This will do the same job than your nested for loop and it's easier to read, to understand and so to maintain than your nested asSequence().

1 Comment

I don't think nests are easy to read at first, that's why I'm looking for some operators that will reduce or remove it, but, must still be readable.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.