データを更新するときにありがちな、そのデータのフィールドの一部だけを変更したい場合への各言語ごとの対処方法。
レコードフィールドの更新用の専用の記述方法がある。
次のようなレコードがあったとして:
pokemon1 = { kind = "electric", name = "Pikachu" }
これの name だけを Voltorb に変更した新しいレコード pokemon2 つくるには:
pokemon2 = { pokemon1 | name = "Voltorb" }
とする。
全体ではこんな感じです:
$ elm repl
> pokemon1 = { kind = "electric", name = "Pikachu" }
{ kind = "electric", name = "Pikachu" }
: { kind : String, name : String }
> pokemon2 = { pokemon1 | name = "Voltorb" }
{ kind = "electric", name = "Voltorb" }
: { kind : String, name : String }
elm version is:
$ elm --version 0.19.1
data class と その copy を使え!
// main.kts
data class Pokemon(val kind: String, val name: String)
val pokemon1 = Pokemon(kind = "electric", name = "Pikachu")
val pokemon2 = pokemon1.copy(name = "Voltorb")
println(pokemon2)
実行:
$ kotlin main.kts
Pokemon(kind=electric, name=Voltorb)
kotlin version is:
$ kotlin -version Kotlin version 2.1.20-release-217 (JRE 17.0.2+8-86)
// main.ts
type Pokemon = {
kind: string,
name: string
}
const pokemon1: Pokemon = { kind: 'electric', name: 'Pikachu' }
const pokemon2: Pokemon = { ...pokemon1, name: 'Voltorb' }
console.log(pokemon2)
実行:
$ deno run main.ts
{ kind: "electric", name: "Voltorb" }
deno version is:
$ deno --version deno 1.44.1 (release, x86_64-unknown-linux-gnu) v8 12.6.228.3 typescript 5.4.5
Claude 3.7 Sonnet Thinking さんに教えてもらった方法:
雰囲気でしか理解してない。
// main.ts
type Pokemon = {
kind: string,
name: string
}
const updatePokemon = (pokemon: Pokemon, newName: string): Pokemon => {
const updateField = <K extends keyof Pokemon>(
field: K,
value: Pokemon[K]
): void => {
const newPokemon = {
...pokemon,
[field]: value
}
return newPokemon
}
return updateField('name', newName)
}
const pokemon1: Pokemon = { kind: 'electric', name: 'Pikachu' }
const pokemon2: Pokemon = updatePokemon(pokemon1, 'Voltorb')
console.log(pokemon2)
フィールドが2つしかないオブジェクトの更新につかうコードではない。 だがしかし、 もしフィールドの数が多い場合は有効なコード。 フィールド名をダイナミックに指定できるから。
以上です。