決定木のプログラミングをしているときに必要になった関数。 これを備忘録としてメモしておきます。
main.kt
data class PokemonAndCount(val name: String, val count: Int)
typealias Condition = (String) -> Boolean
val countif: (List<String>, Condition)-> Int = { list, f->
list.filter { f(it) }.size
}
val toPokemonAndCountList: (List<String>)->List<PokemonAndCount> = { list->
list.distinct().map { pokemonName->
val count = countif(list, { it==pokemonName })
PokemonAndCount(pokemonName, count)
}
}
val toPokemonNameWithMaxCount: (List<String>)->String = { list->
// ここで PokemonAndCount インスタンスの count 値を基準にソート(昇順)、ソート後、リストの最後のそれの name 値を返す.
toPokemonAndCountList(list).sortedWith( compareBy { it.count } ).last().name
}
fun main(){
val pokemonList0 = "Pikachu,Charmander,Squirtle,Pikachu,Metapod".split(",")
println( toPokemonNameWithMaxCount(pokemonList0) ) // → Pickachu
val pokemonList1 = "Squirtle,Pikachu,Charmander,Squirtle,Pikachu,Metapod,Squirtle".split(",")
println( toPokemonNameWithMaxCount(pokemonList1) ) // → Squirtle
}
例によって以下の Makefile でコンパイルと実行を行う。
run: main.jar
java -jar main.jar
main.jar: main.kt
kotlinc main.kt -include-runtime -d main.jar
ポケモン名が String として表現されている部分を Pokemon 型(クラス)に置き換えてみた。
data class Pokemon(val name: String)
data class PokemonAndCount(val pokemon: Pokemon, val count: Int)
typealias Condition = (Pokemon) -> Boolean
val countif: (List<Pokemon>, Condition)-> Int = { list, f->
list.filter { f(it) }.size
}
val toPokemonAndCountList: (List<Pokemon>)->List<PokemonAndCount> = { list->
list.distinct().map { pokemon->
val count = countif(list, { it.name==pokemon.name })
PokemonAndCount(pokemon, count)
}
}
val toPokemonWithMaxCount: (List<Pokemon>)->Pokemon = { list->
toPokemonAndCountList(list).sortedWith( compareBy { it.count } ).last().pokemon
}
fun main(){
val pokemonList0 = "Pikachu,Charmander,Squirtle,Pikachu,Metapod".split(",").map{name-> Pokemon(name)}
println( toPokemonWithMaxCount(pokemonList0) )
val pokemonList1 = "Squirtle,Pikachu,Charmander,Squirtle,Pikachu,Metapod,Squirtle".split(",").map{name-> Pokemon(name)}
println( toPokemonWithMaxCount(pokemonList1) )
}
Pokemon データクラスを追加した上で、 ポケモン名を String として表現した部分を Pokemon に置き換えただけ。 (toPokemonWithMaxCount 関数名は変更した。)
コードはわかりやすくなったが、抽象度は下がった。 抽象度を下げたからコードがわかりやすくなった、というべきか。