Kotlin: объединить два разных списка в один с выбранными данными из обоих списков - PullRequest
0 голосов
/ 05 декабря 2018

Я хочу объединить два списка с разным типом и создать и другой список, который содержит данные из обоих списков.Кроме того, объединение должно происходить только в случае совпадения идентификатора (например, совпадения идентификатора в обоих списках)

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)

. Таким образом, существует список Employee и LaptopInfo, и я хочу добавить EmployeeLaptopInfo в List<EmployeeLaptopInfo> только тогда, когдаСоответствие employeeId в обоих списках

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)
   }

Но в этом случае я не получаю информацию из обоих списков.Есть ли способ сделать это без использования цикла for и эффективным способом.

Ответы [ 3 ]

0 голосов
/ 05 декабря 2018

Я думаю, что было бы лучше сначала создать две карты, одну для ноутбуков и одну для сотрудников, где обе имеют идентификатор employeeId.Затем вы можете сделать следующее:

    val employees = listOf<Employee>()
    val laptops = listOf<LaptopInfo>()

    val laptopsByEmployeeId: Map<Int, List<LaptopInfo>> = laptops.groupBy { it.employeeId }
    val employeesById: Map<Int, Employee> = employees.associateBy { it.employeeId }
    val result = laptopsByEmployeeId.flatMap { (employeeId, laptops) ->
        laptops.mapNotNull { laptop ->
            employeesById[employeeId]?.let { employee ->
                EmployeeLaptopInfo(laptop.laptopId, employeeId, employee.employeeName, employee.address)
            }
        }
    }

Это означает, что вы никогда не зацикливаетесь вокруг одного списка внутри цикла вокруг другого списка, что может быть неэффективно.Вместо этого вы используете карты для быстрого доступа к элементам по их идентификаторам.

(Кроме того, согласно ответу от forpas, я предполагаю, что тип данных для employeeId должен быть одинаковым во всехклассы, например, Int.)

0 голосов
/ 05 декабря 2018

Я оптимизировал решение Йони Гиббса .Идея состоит в том, чтобы filter ноутбуки, в которых employeeId присутствует в Employee.Затем преобразуйте каждый laptop в 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)
        }
    }
}
0 голосов
/ 05 декабря 2018

Я думаю, что у ваших классов есть ошибки в типе данных некоторых свойств, поэтому я изменил их следующим образом:

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)

Если это начальные списки:

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

тогдавы отображаете employeeList, найдя соответствующие значения для employeeId в обоих списках:

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)
        }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...