■ 클래스 FileCSV
앞에서는 한 개의 행 밖에 처리하지 못했습니다. 이제 여러 개 행들을 처리하도록 코드를 추가해 봅시다. 이를 위해 클래스 FileCSV를 만듭니다. 속성 rows는 여러 행을 저장하기 위해 가변 리스트 객체로 선언합니다. 리스트 객체 rows의 원소(=행) 타입은 RowCSV입니다. 메소드 row()는 원소를 리스트 객체 rows에 추가합니다. 재정의 메소드 toString()은 행과 행을 구분하기 위해 줄바꿈 문자('\n')를 추가합니다.
class FileCSV {
private val rows = mutableListOf<RowCSV>()
fun row(makeRow: RowCSV.() -> Unit) {
val rowCSV = RowCSV().apply(makeRow)
rows.add(rowCSV)
}
override fun toString(): String =
rows.joinToString("\n") { "$it" }
}
■ 함수 csv()
CSV파일을 만들기 위한 함수 csv()를 선언합니다. csv()의 형식인자 init의 타입은 확장 함수 타입입니다. 클래스 FileCSV의 객체는 확장 함수 init()를 호출합니다. 함수 csv()는 함수 row()를 호출하고, 함수 row()는 다시 함수 column()을 호출하는 방식으로 동작합니다. 아래 예에서 보인 것처럼 함수 csv()는 CSV 빌더로 동작합니다.
class RowCSV { ... }
class FileCSV { ... }
fun csv(init: FileCSV.() -> Unit) = FileCSV().apply(init)
fun main() {
val myCSV = csv {
row {
column("영웅")
column("특징")
column("직업")
}
row {
column("홍길동")
column("둔갑술")
column("의적")
}
}
println(myCSV.toString())
// 영웅, 특징, 직업
// 홍길동, 둔갑술, 의적
}
■ row 만을 사용하도록 위 코드를 수정해 봅시다.
csv > row > column 방식을 csv > row의 2단계로 줄일 수 있습니다. 먼저 속성 rows의 원소 타입을 RowCSV에서 List<String>으로 수정합니다. 클래스 RowCSV에서 메소드 column()이 했던 역할을 클래스 FileCSV의 메소드 row()에서 이를 함께 처리하도록 변경합니다. row()의 형식인자가 가변 매개변수(vararg)를 받을 수 있도록 수정합니다. 재정의 메소드 toString()은 리스트의 리스트 컬렉션 객체를 출력하도록 수정해야 합니다. 바깥 쪽 리스트의 원소는 행(row)에 해당하기 때문에 joinToString()의 구분자는 줄바꿈 문자('\n')입니다. 안쪽 리스트의 원소는 열(column)에 해당하기 때문에 joinToString()의 구분자는 쉼표(,)입니다.
수정한 CSV 빌더에서는 한 행에 해당하는 원소를 한꺼번에 입력할 수 있습니다. 이렇게 변환된 CSV를 파일로 저장하기 위해 메소드 saveToFile()을 추가했습니다.
import java.io.File
class FileCSV {
private val rows = mutableListOf<List<String>>()
fun row(vararg columns: String) {
rows.add(columns.toList())
}
override fun toString(): String =
rows.joinToString("\n") { row ->
row.joinToString (", "){ "$it" }
}
fun saveToFile(fileName: String) {
File(fileName).writeText(this.toString())
}
}
fun csv(init: FileCSV.() -> Unit) = FileCSV().apply(init)
fun main() {
val myCSV = csv {
row ("영웅", "특징", "직업")
row ("홍길동", "둔갑술", "의적")
row ("이순신", "전략전술의 달인", "팔도수군도원수")
row ("박문수", "암행어사", "정치인")
}
myCSV.saveToFile("output.csv")
// println(myCSV.toString())
}
'코틀린' 카테고리의 다른 글
코틀린: DSL(1/2) - CSV 빌더를 만들어 봅시다. (0) | 2025.01.17 |
---|---|
4장 - (아주 쉽게 설명한) 다양한 sealed 클래스를 만들어 봅시다. (0) | 2025.01.17 |
3장 - (아주 쉽게 설명한) 함수를 람다 식으로 변환해 봅시다(2/2). (0) | 2025.01.17 |
3장 - (아주 쉽게 설명한) 함수를 람다 식으로 변환해 봅시다(1/2). (0) | 2025.01.17 |
3장 - (아주 쉽게 설명한) 조합을 계산하는 함수를 만들어 봅시다. (0) | 2025.01.17 |