Back-End (web)

[Kotlin] list.groupBy

햄과함께 2019. 10. 17. 21:35
320x100
data class Notice(val no: Long,
                  val name: String)

data class File(val no: Long,
                val name: String,
                val noticeNo: Long)

data class NoticeWithFiles(val no: Long,
                           val name: String,
                           val files: List<File>)
val notices = listOf(Notice(1L, "1"), Notice(2L, "2"), Notice(3L, "3"))
val files = listOf(File(1L, "1", noticeNo = 1),
    File(2L, "2", noticeNo = 1),
    File(3L, "3", noticeNo = 1),
    File(4L, "4", noticeNo = 2))

Notice, File 리스트들을 가지고 있다고 할 때, 이들을 조합하여 NoticeWithFiles 리스트를 만들려고 한다.

이를 위해 먼저 File 리스트를 같은 noticeNo를 가지면 이들을 모아서 하나의 리스트를 만들기로 했다.

-> Map(key: noticeNo, value: List<File>)


val fileMap = mutableMapOf<Long, MutableList<File>>()
files.forEach {
    val key = it.noticeNo
    val list = fileMap[key] ?: mutableListOf()
    list.add(it)
    fileMap[key] = list
}

위와 같이 File 리스트를 for문 돌려서 map을 만든다음 이를 사용해도 된다.

하지만 코드가 장황한 느낌이다.

 

 groupBy 를 사용하면 value가 list인 map을 쉽게 만들 수 있다.

val files: List<File>

// key : noticeNo
// value : noticeNo가 key와 같은 List<File>
val fileMap = files.groupBy{ it.noticeNo }

File List인 files에 groupBy를 위와 같이 적용하면

key가 noticeNo,

value가 noticeNo를 가지는 File의 리스트가 된다.

groupBy 결과


fun main(args: Array<String>) {
    val notices = listOf(Notice(1L, "1"), Notice(2L, "2"), Notice(3L, "3"))
    val files = listOf(File(1L, "1", noticeNo = 1),
        File(2L, "2", noticeNo = 1),
        File(3L, "3", noticeNo = 1),
        File(4L, "4", noticeNo = 2))

    val fileMap = files.groupBy{ it.noticeNo }
    println(fileMap)

    // #1
    val noticeWithFiles : List<NoticeWithFiles> = notices.map{ notice ->
        NoticeWithFiles(notice.no, notice.name, fileMap.getOrDefault(notice.no, emptyList()))
    }

    assertEquals(3, noticeWithFiles[0].files.size)
    assertEquals(1, noticeWithFiles[1].files.size)
    assertEquals(0, noticeWithFiles[2].files.size)

    noticeWithFiles.forEach {
        println(it)
    }
}

NoticeWithFile 리스트를 만드는건 #1 처럼 map을 이용했다. (참고 - 전체코드)

 

noticeWithFiles 결과

참고 : [Kotlin 문서] groupBy

320x100