How to delete some elements from list in kotlin
Solution 1
Here is a solution for you. Notice in your OP you did not actually reference Properties class at all from your Product class (so you wouldn't have been able to filter products by properties because they don't have any relationship in your code).
Also, you are using var. Properties with var are mutable (meaning they can be changed after object creation). It's generally better to use val and, if you need to mutate a property of an object, create a new instance with the updated properties (much better for multithreading and async code).
@Test
fun testFilter() {
// Properties of a product
data class Properties(val city: String, val day: Int, val month: Int, val yearProp: Int, val dayEnd: Int, val monthEnd: Int, val yearEndProp: Int, val priceFrom: Int, val priceTo: Int)
// A product (notice it references Properties)
data class Product(val productProperties: Properties, val title: String, val price: String, val photoId : String)
// Let's pretend these came from the server (we parsed them using Gson converter)
val productA = Product(Properties("New York", 0, 0, 0, 0, 0, 0, 0, 0), "Sweets", "$1", "1")
val productB = Product(Properties("Boston", 0, 0, 0, 0, 0, 0, 0, 0), "Eggs", "$2", "1")
val productC = Product(Properties("New York", 0, 0, 0, 0, 0, 0, 0, 0), "Flour", "$1", "1")
// Create a list of the products
val listOfProducts = mutableListOf(productA, productB, productC)
// Filter the products which have new york as the city in their properties
val filteredNewYorkProducts = listOfProducts.filter { it.productProperties.city == "New York" }
// Assert that the filtered products contains 2 elements
Assert.assertTrue(filteredNewYorkProducts.size == 2)
// Assert that the filtered products contains both product A and B
Assert.assertTrue(filteredNewYorkProducts.contains(productA))
Assert.assertTrue(filteredNewYorkProducts.contains(productB))
}
Solution 2
Here is an example to remove items with certain conditions from a list in place. This example removes even numbers from a list of integers.
var myLists = mutableListOf(1,2,3,4,5,6,7,8,9)
myLists.removeAll{ it % 2 == 0 }
println(myLists)
prints:
[1, 3, 5, 7, 9]
Arsen Saruhanyan
Updated on June 24, 2022Comments
-
Arsen Saruhanyan almost 2 years
I had a problem with how to remove elements that do not match certain parameters. For example, I have two data classes: First and Second First one contains properties for second i.e. city, price etc:
data class Properties(val city: String, val day: Int, val month: Int, val yearProp: Int, val dayEnd: Int, val monthEnd: Int, val yearEndProp: Int, val priceFrom: Int, val priceTo: Int)
Second data class for Item:
data class Product(var title: String, var price: String, var photoId : String)
I'm parsing data for Products by this code from json:
val gson = GsonBuilder().setPrettyPrinting().create() val inputStream : Reader = context.getResources().openRawResource(R.raw.products).reader() var productList: ArrayList<Product> = gson.fromJson(inputStream, object : TypeToken<List<Product>>() {}.type) productList.forEach { println(it) }
This is JSON File:
[ { "city": "New York", "title": "Banana", "price": "$1,99" "photoId": "someurl" }, { "city": "New York", "title": "Strawberry", "price": "$1,99" "photoId": "someurl" }, { "city": "Philadelphia", "title": "Banana", "price": "$4,99" "photoId": "someurl" } ]
So, I want to filter it. If user match "New York" then in list must be only items with "city":"New York". And yes, this is just for example, do not pay attention to all the stupidity that I wrote there :D
Or may be I should filter items when I adding it? But if so, then how to do it?
-
Arsen Saruhanyan about 6 yearsHm. I've tried it and found some questions. Please do not scold me, only now I learned about this possibility. So, I've found that I can just use removeIf({ s -> s.city != MainActivity.props.city}) (The problem is that I fill Properties in MainActivity). And it works.But, is this solution ok? (heh)
-
Arsen Saruhanyan about 6 yearsOuch. It's Android Nougat-only.
-
Thomas Cook about 6 yearsI don't know removeIf, but, it sounds like it will remove elements from the list it's called on (whereas filter creates a new list with the elements filtered out). In general, these kind of functions are called higher order functions as they take a function as input. For instance, the
filter
function takes in a function that returns a boolean. It then calls the passed function on each element in the list and if it returns true it adds that element to a new list, else it skips. The function passed intofilter
is known as apredicate
. -
Arsen Saruhanyan about 6 yearsOh, well. I think I figured it out. Thanks, it helps.
-
Thomas Cook about 6 yearsNo problem, practice using these higher order functions on different collections.
-
allenjom over 4 yearsThank you!! I was looking at loops and streams and iterators and if. Too easy!
-
Ajay about 4 yearshey @ThomasCook how can we filter/remove properties if each product has a list of properties ?
-
Michel Fernandes over 3 yearsI's an amazing solution! Thanks!