Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mapping arrays to list of objects kotlin

I'm wondering about methods of mapping multiple arrays into one list of object.

I mean e.g. I have

val a = arrayOf("A1","A2","A3")
val b = arrayOf("B1","B2","B3")

and

data class SomeClass(val v1:String, val v2:String)

I want to parse it in elegant way to have list like that:

val list = listOf(SomeClass("A1","B1"),SomeClass("A2","B2"),SomeClass("A3","B3"))

I assume they are of the same length. The only way I thought of is:

val list = mutableListOf<SomeClass>() 
for (i in a.indices) 
            array.add(SomeClass(a[i],b[i])

Is there a better, more elegant solution (maybe using Collecions.zip or Array.map)?

like image 476
Jakub Mosakowski Avatar asked Aug 09 '18 11:08

Jakub Mosakowski


People also ask

How do I make a list of objects in Kotlin?

Create a new List using the Kotlin standard library function listOf() , and pass in the elements of the list as arguments separated by commas. listOf(1, 2, 3, 4, 5, 6) returns a read-only list of integers from 1 through 6.

How do I map one list to another in Kotlin?

You can use the map() function to easily convert a list of one type to a list of another type. It returns a list containing the results of applying the specified transform function to each element in the original list. That's all about conversion between lists of different types in Kotlin.

How do you create an Array of objects in Kotlin?

There are two ways to define an array in Kotlin. We can use the library function arrayOf() to create an array by passing the values of the elements to the function. Since Array is a class in Kotlin, we can also use the Array constructor to create an array.

What is the difference between Arraylist and list in Kotlin?

The major difference from usage side is that Arrays have a fixed size while (Mutable)List can adjust their size dynamically. Moreover Array is mutable whereas List is not. Furthermore kotlin. collections.


2 Answers

Try Array.zip and then map:

val list = a.zip(b)
            .map { SomeClass(it.first, it.second) }

or if you like it more:

val list = a.zip(b)
            .map { (a, b) -> SomeClass(a, b) }

Note that if both arrays differ in size, the additional values are ignored. Note also that this will create intermediate Pairs (which is the default transformation function of zip). Even though I like the explicit map more, @hotkeys solution regarding the overloaded method is more appropriate (you spare that hidden Pair-transformation):

val list = a.zip(b) { a, b -> SomeClass(a, b) }

And where the overloaded method probably shines, is when using references instead:

a.zip(b, ::SomeClass)

Which will work as long as you have a constructor matching the zipped arguments and doesn't work out of the box for the Pair (yet?).

like image 139
Roland Avatar answered Sep 22 '22 07:09

Roland


Improving on @Roland's answer, you can use the zip overload that accepts a two-argument function for mapping the pairs immediately:

val result = a.zip(b) { x, y -> SomeClass(x, y) }
like image 39
hotkey Avatar answered Sep 22 '22 07:09

hotkey