Reputation: 379
So in this case I have three array that I want to map into a list of object (The objects has three parameters as well).
I have three arrays allProductCodeList
, allProductNameList
, and allProductQtyList
(Content of this array is from a Retrofit Client response)
allProductCodeList = response.body()?.data?.map { it?.stkProdcode }!!
allProductNameList = response.body()?.data?.map { it?.proName }!!
allProductQtyList = response.body()?.data?.map { it?.stkAllqty }!!
This is the content of the array I printed into the LogCat:
[![enter image description here][2]][2]
This is the Data class which I want to parse these arrays into:
data class ProcodeRecommendationListDataClass(
val procode: String?,
val productName: String?,
val qty: Int?
)
What I want to do is parse these three array into a list that will looks like:
[ProcodeRecommendationListDataClass("0100009","", 2),ProcodeRecommendationListDataClass("0100061","", 1),ProcodeRecommendationListDataClasslass("0100062","", 6)]
I've done it when I only have two arrays to map (I use this solution for it). But now it I have three arrays, I confused.
If there's any detail I miss to point out, Just let me know !
Upvotes: 0
Views: 2613
Reputation: 17095
One forward straight way is to use one more zip
- someone once said all problems are solved with one more level of inderection:
allProductCodeList
.zip(allProductNameList)
.zip(allProductQtyList)
.map { (codeAndName, qt) ->
ProcodeRecommendationListDataClass(
codeAndName.first,
codeAndName.second,
qt
)
}
It doesn't look super pretty, but it should be ok.
Another way is to create your own zip that takes 2 lists:
fun <X, Y, Z, R> List<X>.zipWith(l1: List<Y>, l2: List<Z>, transform: (X, Y, Z) -> R): List<R> {
val length = min(min(size, l1.size), l2.size)
val result = mutableListOf<R>()
for (i in 0 until length) {
result.add(transform(get(i), l1[i], l2[i]))
}
return result
}
fun main() {
val k = allProductCodeList.zipWith(allProductNameList, allProductQtyList) { code, name, qt ->
ProcodeRecommendationListDataClass(
code,
name,
qt
)
}
println(k)
}
Basically extends a list of X
that takes 2 other lists. It iterates through them applying the transform
method (this is so you can map the elements as you go).
This will iterate always the smallest amount of elements - in other words, you won't get more elements than the smallest list. I can't be sure, but I assume the default implementation does something similar.
Upvotes: 3
Reputation: 2117
You can use mapIndexed
instead of map. use index to get third data.
val list = allProductCodeList.zip(allProductNameList)
.mapIndexed { index, pair -> SomeClass(pair.first, pair.second,allProductQtyList[index]) }
Upvotes: 0
Reputation: 2254
1. This is you three arrays
allProductCodeList = response.body()?.data?.map { it?.stkProdcode }!!
allProductNameList = response.body()?.data?.map { it?.proName }!!
allProductQtyList = response.body()?.data?.map { it?.stkAllqty }!!
2. Make A New List
List<ProcodeRecommendationListDataClass> finalList = List()
3. Run a for loop with any of three array size with indices;
for(pos in allProductCodeList.indices){
finalList.add(ProcodeRecommendationListDataClass(allProductCodeList[pos],
allProductNameList[pos],
allProductQtyList[pos] ))
}
Now finalList is your result.
Upvotes: 3
Reputation: 9732
Why not just create objects in place?
val allProducts = response.body()?.data?.map {
ProcodeRecommendationListDataClass(it?.stkProdcode, it?.proName, it?.stkAllqty)
} ?: emptyList()
Upvotes: 1