プログラミングの勉強を始めたあたりで次の様なコードを書くことがよくあります。
tmp = numbers[i]; numbers[i] = numbers[j]; numbers[j] = tmp;
具体的には、並び替え処理を自分で書くという課題の中で配列中の要素を直接入れ替える時に書くコードです。並び替えは言語組み込みの関数を用いることが多いため実務で使うことは珍しいですが、これを書いたことがある人は多いはずです。tmp のような一時変数に値を退避させないせいで numbers[i] と numbers[j] に同じ値が格納されてしまう失敗はあるあるです。
配列中の要素を直接入れ替えるコードですが、実は一時変数や特別な関数を使わずとも正常に入れ替えられる言語が多いです。例えば JavaScript では次の様に書けます。
const numbers = [1, 2, 3]; [numbers[0], numbers[1]] = [numbers[1], numbers[0]]; console.log(numbers);// [2, 1, 3]
分割代入を用いることで右辺に入れ替え前の入れ替え対象を両方とも展開し、左辺の代入先に入れ替え対象を指定します。これにより、一時変数を使わずとも入れ替えができます。
上記例は JavaScript ですが、他にも同じことができる言語は少なくありません。これは例えば以下の様にできます。
<?php $numbers = [1, 2, 3]; [$numbers[1], $numbers[0]] = [$numbers[0], $numbers[1]]; echo json_encode($numbers);// [2, 1, 3]
# python numbers = [1, 2, 3] numbers[1], numbers[0] = (numbers[0], numbers[1]) print(numbers)# [2, 1, 3]
// Go package main import "fmt" func main() { arr := []int{1, 2, 3} arr[1], arr[0] = arr[0], arr[1] fmt.Println(arr)// [2 1 3] }
# Ruby numbers = [1, 2, 3] numbers[1], numbers[0] = [numbers[0], numbers[1]] print numbers # [2, 1, 3]
// Rust fn main(){ let mut numbers = [1, 2, 3]; (numbers[1], numbers[0]) = (numbers[0], numbers[1]); println!("{:?}", numbers);// [2, 1, 3] }
分割代入は少なくない言語が機能として持っています。言語によって機能名が違ったり、そもそも名前がなかったりすることもありますが大体同じ機能です。全体の並び替えをする程でないけど要素を入れ替えたい時などに、このやり方が思い浮かぶと案外見やすいコードになってくれます。