Hey I have a huge list coming from server. I am adding some data at top of list. I want to remove data from the list. I have nested list in which I need to find the element in nested list.
fun categoriesList() = listOf(
Categories("21", "physical", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
Categories("2211", "mind", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
Categories("22131", "motorized", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
Categories("2134124", "coordination", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
Categories("211243", "animal-supported", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
)
Categories.kt
data class Categories(
val id: String? = null, val title: String? = null, val subTopic: List<SubTopic>? = null
)
SubTopic.kt
data class SubTopic(
val id: String? = null, val title: String? = null, var priceId: String? = null
)
main.kt
var categoryList: List<Categories>? = null
fun main() {
categoryList = categoriesList()
categoryList?.add(0, Categories("0", "physical-ktm", listOf(SubTopic("1", "vivek"))))
}
So I want to find title = "Vivek"
if that found I want to drop my whole list index 0 element data. Important I only need to check element at index 0. I don't want to iterate whole list. If found the data in index 0 drop it otherwise leave it the iteration. So what is efficient way of doing this in kotlin idiomatic way. Can someone guide me. Thanks
UPDATE
categoryList?.forEachIndexed { index, data->
println("$index index -> $data")
}
console
0 index -> Categories(id=0, title=physical-ktm, subTopic=[SubTopic(id=1, title=vivek, priceId=null)])
1 index -> Categories(id=21, title=physical, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
2 index -> Categories(id=2211, title=mind, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
3 index -> Categories(id=22131, title=motorized, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
4 index -> Categories(id=2134124, title=coordination, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
5 index -> Categories(id=211243, title=animal-supported, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
I only want to search in 0 index
of Categories
and if title = "vivek"
is found in subTopic
then I want to drop 0 index
from Categories
and stop iteration. If data is not found at all in subTopic
then I don't won't to iterate whole list of Categories
.
After @Tenfour04 suggestion I added this code
var categoryList: MutableList<Categories>? = null
fun main() {
categoryList = categoriesList().toMutableList()
categoryList?.add(0, Categories("0", "physical-ktm", listOf(SubTopic("1", "vivek"))))
println("After Add")
categoryList?.forEachIndexed { index, categories ->
println("$index index -> $categories")
}
val matchingIndex = categoryList?.indexOfFirst { it.subTopic?.first()?.title == "vivek" }
if (matchingIndex != null && matchingIndex >= 0) {
categoryList = categoryList?.mapIndexed { index, it ->
if (index == matchingIndex)
it.copy(subTopic = it.subTopic?.drop(1))
else
it
} as MutableList<Categories>?
}
println("After operation")
categoryList?.forEachIndexed { index, categories ->
println("$index index -> $categories")
}
}
Actual Output
After Add
0 index -> Categories(id=0, title=physical-ktm, subTopic=[SubTopic(id=1, title=vivek, priceId=null)])
1 index -> Categories(id=21, title=physical, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
2 index -> Categories(id=2211, title=mind, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
3 index -> Categories(id=22131, title=motorized, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
4 index -> Categories(id=2134124, title=coordination, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
5 index -> Categories(id=211243, title=animal-supported, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
After operation
0 index -> Categories(id=0, title=physical-ktm, subTopic=[])
1 index -> Categories(id=21, title=physical, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
2 index -> Categories(id=2211, title=mind, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
3 index -> Categories(id=22131, title=motorized, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
4 index -> Categories(id=2134124, title=coordination, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
5 index -> Categories(id=211243, title=animal-supported, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
Expect Output
After Add
0 index -> Categories(id=0, title=physical-ktm, subTopic=[SubTopic(id=1, title=vivek, priceId=null)])
1 index -> Categories(id=21, title=physical, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
2 index -> Categories(id=2211, title=mind, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
3 index -> Categories(id=22131, title=motorized, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
4 index -> Categories(id=2134124, title=coordination, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
5 index -> Categories(id=211243, title=animal-supported, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
After operation
0 index -> Categories(id=21, title=physical, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
1 index -> Categories(id=2211, title=mind, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
2 index -> Categories(id=22131, title=motorized, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
3 index -> Categories(id=2134124, title=coordination, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
4 index -> Categories(id=211243, title=animal-supported, subTopic=[SubTopic(id=1, title=abc, priceId=null), SubTopic(id=2, title=bjhef, priceId=null)])
I want to remove whole Categories
object which is present at index 0.
CodePudding user response:
So if I understand the question correctly, you want to eliminate the first – and only the first – subtopic for each category in categoriesList if its title is "Vivek":
data class SubTopic(
val id: String? = null,
val title: String? = null,
var priceId: String? = null
)
data class Categories(
val id: String? = null,
val title: String? = null,
val subTopic: List<SubTopic>? = null
)
val categoriesList = listOf(
Categories("21", "physical", listOf(SubTopic("1", "abc"), SubTopic("2", "Vivek"))),
Categories("2211", "mind", listOf(SubTopic("1", "Vivek"), SubTopic("2", "bjhef"))),
Categories("22131", "motorized", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
Categories("2134124", "coordination", listOf(SubTopic("1", "Vivek"), SubTopic("2", "Vivek"))),
Categories("211243", "animal-supported", listOf(SubTopic("1", "abc"), SubTopic("2", "bjhef"))),
)
var categoryList = categoriesList
.map {
it.copy(subTopic = it.subTopic
?.filterIndexed { index, subTopic -> (index == 0 && subTopic.title != "Vivek") || index > 0 }
)
}
categoryList.forEach(::println)
CodePudding user response:
My understood description of the task: Find the first (and only first) Categories in categoriesList
that has a subList
whose first SubTopic has a title
of "vivek"
. If it is found, set categoriesList
to a new List where the Categories where it was found has been replaced with a new Categories instance whose subList
has the matched first SubTopic removed.
If prioritizing clarity, I would use map
even though it will copy the list regardless of whether any Categories are modified. And I'd use a Boolean variable to determine whether the search must continue.
var itemFound = false
categoriesList = categoriesList.map {
if (!itemFound && it.subTopic?.first()?.title == "vivek") {
itemFound = true
it.copy(subTopic = it.subTopic?.drop(1))
} else {
it
}
}
If prioritizing performance, I would search using indexOf
so I would only create the new list if necessary. But really, if performance is truly this critical we really should be using mutable collections and data classes. That might not be possible if doing list comparisons, of course.
val matchingIndex = categories.indexOfFirst { it.subTopic?.first()?.title == "vivek"}
if (matchingIndex >= 0) {
categoriesList = categoriesList.mapIndexed { index, it ->
if (index == matchingIndex)
it.copy(subTopic = it.subTopic?.drop(1))
else
it
}
}
Edit: based on your new comment, I think this is what you are asking for now. Quite a bit simpler.
if(categoriesList.first().subTopics.orEmpty().any { it.title == “vivek” }) {
categoriesList = categoriesList.drop(1)
}