1
votes

How to transform a List into a new List by excluding a property in T. For instance if User data class has 10 properties, I need to transform List into a new List without one particular property in User . New List like List data class User(val name: String, val age: Int)

var userList = mutableListOf<User>()

var nameList= userList.map { it.name }

If a List to be created without property 'age'. Like

var withoutAgeList
3
If you need a list of strings then you've already created one via a map functionNikolay Kulachenko
I want to exclude a property . For instance if User data class has 10 properties, I need to transform List<User> into a new List without one particular property in User . New List like List<UserWithoutAge>.Aravindraj
What do you mean by "excluding a property"? An instance will always point to all of its members, even if some are null. As other answers say, you either create another class or make this variable null. do you want to serialize this object? please clarify the use case you are trying to solvecrgarridos

3 Answers

5
votes

In your first example:

var userList = mutableListOf<User>()
var nameList= userList.map { it.name }

The question "What's the type of nameList?" has a simple answer: List<String>. So let me ask you a similar question: What's the type of withoutAgeList? The answer to that question informs the answer to your question.

Perhaps a user without the age property is a separate AgelessUser class, meaning withoutAgeList is of type List<AgelessUser>. In that case, I suggest either a constructor or a factory function that builds AgelessUser from User, and you want one of these:

val withoutAgeList =  userList.map { AgelessUser(it) } // constructor
val withoutAgeList =  userList.map { agelessUserOf(it) } // factory

Alternatively, maybe the age property in User is nullable and immutable, and you want to represent users without an age as a regular User where age=null. In this case, you could copy the Users and override the age field

// TODO: pass all the other fields too
val withoutAgeList =  userList.map { User(it.name, null) } 

Assuming Users is a data class, we can avoid explicitly naming all fields by making use of copy():

val withoutAgeList =  userList.map { it.copy(age = null) } 

Maybe the age property is nullable and mutable — and you actually want to change the users in place instead of copying them. This is somewhat risky and I don't advocate doing it this way unless you really know what you're doing though.

userList.forEach { it.age = null } 
// They're actually the same list!
val withoutAgeList =  userList
1
votes

In such a simple case you can map a list of Users into a list of strings:

val names: List<String> = userList.map(User::name)

Or you can declare a DTO and map into the latter:

class UserWithoutAge(val name: String)

val usersWithoutAge: List<UserWithoutAge> = userList.map { UserWithoutAge(it.name) }

P.S. you don't have to write an explicit type

0
votes

You can use the Object Oriented approach:

data class User(val name: String, val age: Int)

data class UserNoAge(var name: String) {
    constructor(user: User) : this(user.name)
}

var userList = listOf(User("John", 25), User("Jane", 30))
var userNoAge: List<UserNoAge> = mutableListOf<UserNoAge>()

userNoAge = userList.map{ UserNoAge(it) }

println(userNoAge) // [UserNoAge(name=John), UserNoAge(name=Jane)]