Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: Merge two different list into one with selected data from both lists

I want to merge two list with different type and create and another list which contains data from both lists. Also, merging should only happen when identifier match(like id match in both list)

Employee(val employeeId: Int,
         val employeeName: String,
         val address: String)

LaptopInfo(val laptopId: Int,
         val employeeId: String,
         val team: String)

EmployeeLaptopInfo(val laptopId: Int,
         val employeeId: String,
         val employeeName: String,
         val address: String)

So there is list of Employee and LaptopInfo and I want to add EmployeeLaptopInfo to List<EmployeeLaptopInfo> only when employeeId match in both lists

val employeeLaptopInfoList = mutableListOf<EmployeeLaptopInfo>()
val employeeIds = employeeList.map { it.employeeId }.toSet()

lapTopInfoList.filter { employeeIds.contains(it.employeeId) }
   .map {
      val employeeLaptopInfo = EmployeeLaptopInfo(it.laptopId, laptopId.employeeId, "can't get info", "can't get info")
      employeeLaptopInfoList.add(employeeLaptopInfo)
   }

But this way I don't get details from both list. Is there any way to do it without using for loop and in efficient manner.

like image 427
user1288005 Avatar asked Dec 05 '18 13:12

user1288005


2 Answers

I've optimized Yoni Gibbs's solution. The idea is to filter the laptops in which the employeeId is present in Employee. Then transform each laptop into EmployeeLaptopInfo.

data class Employee(val employeeId: Int, val employeeName: String, val address: String)

data class LaptopInfo(val laptopId: Int, val employeeId: Int, val team: String)

data class EmployeeLaptopInfo(val laptopId: Int, val employeeId: Int, val employeeName: String, val address: String)

fun main(args: Array<String>) {
    val employees = listOf<Employee>()
    val laptops = listOf<LaptopInfo>()

    val employeesById: Map<Int, Employee> = employees.associateBy { it.employeeId }

    val result = laptops.filter { employeesById[it.employeeId] != null }.map { laptop ->
        employeesById[laptop.employeeId]?.let { employee ->
            EmployeeLaptopInfo(laptop.laptopId, laptop.employeeId, employee.employeeName, employee.address)
        }
    }
}
like image 120
Abhay Agarwal Avatar answered Sep 28 '22 10:09

Abhay Agarwal


I think your classes have errors in the data type of some properties, so I changed them like this:

class Employee(val employeeId: Int, val employeeName: String, val address: String)
class LaptopInfo(val laptopId: Int, val employeeId: Int, val team: String)
class EmployeeLaptopInfo(val laptopId: Int, val employeeId: Int, val employeeName: String, val address: String)

If these are the initial lists:

val employeeList = mutableListOf<Employee>()
val laptopInfoList = mutableListOf<LaptopInfo>()

then you map employeeList by finding corresponding values for employeeId in both lists:

val employeeLaptopInfoList =
        employeeList.mapNotNull { emp ->
            val laptop = laptopInfoList.find { it.employeeId == emp.employeeId }
            if (laptop == null) null 
            else EmployeeLaptopInfo(
                laptop.laptopId,
                emp.employeeId,
                emp.employeeName,
                emp.address)
        }
like image 43
forpas Avatar answered Sep 28 '22 09:09

forpas