はじめに
少し前にPHPのarray系の組込み関数を自作関数で作って遊んで書いてた時があり最近、久しぶり遊んでみました。脳トレになるし、他にもいろいろな書き方を思いついて実装出来ます。さらに、こんな組込み関数あったんだってなるのでかなりいいと思うので今回は、array_combine
を自作関数で実装してみます。
皆さんも是非この記事を読み終わった後に、組込み関数を自作関数で作成してみて遊んでみてください。
目次
- array_combine仕様
- for文 実装
- 再帰関数 実装
- 再帰関数+ポインタ操作+参照渡し 実装
- 再帰関数+ポインタ操作+参照渡し+高階関数+コールバック関数 実装
- 最後に
array_combine仕様
まず最初に公式のページでarray_combine
の仕様について見てみましょう。
array_combine ( array $keys , array $values ) : array
keys 配列の値をキーとして、また values 配列の値を対応する値として生成した 配列 を作成します。
引用元 https://www.php.net/manual/ja/function.array-combine.php
第一実引数にkeyにしたい配列を指定し、第二実引数にvalue値にしたい配列を指定すると、key => valueで配列を作成してくれるというこですね。
例
$a = array('green', 'red', 'yellow');
$b = array('avocado', 'apple', 'banana');
$c = array_combine($a, $b);
print_r($c);
//Array
//(
// [green] => avocado
// [red] => apple
// [yellow] => banana
//)
上記の様な配列が完成します。for文を使用せずに作成出来るのですっきりしますね。
今回前提として
エラーが発生する時の例外処理は無視します。
使用するデータは、例で使用したデータをそのまま使用します。
自作関数に渡す配列の第一実引数,第二実引数は同じ数にします。
for文 実装
まず、最初はfor文で実装をしてみます。
function _array_combine($array_keys, $array_values) {
$result = [];
for ($i = 0; $i < count($array_keys); $i++) {
$result[$array_keys[$i]] = $array_values[$i];
}
return $result;
}
$c = _array_combine($a, $b);
print_r($c);
ポイントは、どのように第一実引数をkey、第二実引数をvalueに設定するかだと思います。今回は、受け取った配列をcount
関数を使用して回数分for文を回し
$result[第一実引数の値をkeyに設定]=ここに第二実引数の値をvalueに設定
といった風に実装します。
次に、再帰関数で実装します。
再帰関数 実装
再帰関数で実装するので、まず最初にどのようにして戻ってこれるかを考えていきます。戻ってこれる処理を書かない場合、処理が実行し続けることになってしまいます。
下記の処理は再帰関数の例です。
// helloが2回出力されて処理が終わる
$num1 = 0;
function recursion($num2) {
echo 'hello';
$num2++;
if ($num2 !== 2) {
recursion($num2);
}
return;
}
recursion($num1);
$num2
が2の時以外は実行される処理なので$num2
が2の時には上に戻ってこれるので処理が止まります。
それを念頭に置いて、array_combine
を再帰関数で実装したのが下記の処理です。
function _array_combine($array_keys, $array_values) {
$result = [];
$result[$array_keys[0]] = $array_values[0];
array_shift($array_keys);
array_shift($array_values);
if (count($array_keys) > 0) {
$result = array_merge($result, _array_combine($array_keys, $array_values));
}
return $result;
}
$c = _array_combine($a, $b);
print_r($c);
array_shift
を使用して配列の先頭を削除します。index
は0からまた割り振られます。
そしてここで、ポイントになる上に戻ってこれる処理を書きます。$array_keys
の配列が0以上の時はまだ作成が終わってないということなので関数をもう一度実行します。0になった時に、上に戻ってこれるようにします。
次に、再帰関数+ポインタ操作+参照渡しを実装します。
再帰関数+ポインタ操作+参照渡し 実装
function getNextValue(&$array_keys1, &$array_values1) {
$value1 = current($array_keys1);
$value2 = current($array_values1);
next($array_keys1);
next($array_values1);
return [$value1, $value2];
}
function isEndValue($array_keys2, $value2) {
return end($array_keys2) === $value2;
}
function _array_combine($array_keys, $array_values) {
$result = [];
$array = getNextValue($array_keys, $array_values);
$result[$array[0]] = $array[1];
if (!isEndValue($array_keys, $array[0])) {
$result = array_merge($result, _array_combine($array_keys, $array_values));
}
return $result;
}
$c = _array_combine($a, $b);
print_r($c);
ポイントになる部分としては、参照渡しとポインタ操作になると思います。
function getNextValue(&$array_keys1, &$array_values1) {
$value1 = current($array_keys1);
$value2 = current($array_values1);
next($array_keys1);
next($array_values1);
return [$value1, $value2];
}
上記の処理では、$array_keys
と$array_values
を参照渡しで渡してます。受けっとた仮引数の$array_keys1
と$array_values1
をcurrent
を使用して配列内の現在のポインタにある値を取得しています。
currentの仕様
current ( array|object $array ) : mixed
各配列は、"カレント"の要素へのポインタを有しています。 このポインタは、配列に挿入された最初の要素を指すように初期化されます。
次にnext
を使用して、配列内部のポインタを進めます。
nextの仕様
next ( array|object &$array ) : mixed
next() は、ひとつの違いを除いて current() と同じです。 next() は要素を返す前に内部配列ポインタをひとつ先に進めます。 つまり、次の配列要素を返すとともに内部配列ポインタをひとつ進めるということです。
最後に、key
とvalue
になる値を返します。
次に下記の関数が呼び出されます。
function isEndValue($array_keys2, $value2) {
return end($array_keys2) === $value2;
}
$array_keys
を実引数で渡してあげ、その配列のポインタを最後の要素に設定して現在の配列の値が最後の要素と一致した場合は、上に戻ってくるようにするので_array_combine
を実行しません。
endの仕様
end ( array|object &$array ) : mixed
end() は array の内部ポインタを最後の要素まで進め、その値を返します。
次に、再帰関数+ポインタ操作+参照渡し+高階関数+コールバック関数で実装します。
再帰関数+ポインタ操作+参照渡し+高階関数+コールバック関数 実装
function getNextValue(&$array_keys1, &$array_values1) {
$value1 = current($array_keys1);
$value2 = current($array_values1);
next($array_keys1);
next($array_values1);
return [$value1, $value2];
}
function isEndValue($array_keys2, $value2) {
return end($array_keys2) === $value2;
}
function _array_combine($array_keys, $array_values, $callback) {
$result = null;
$array = getNextValue($array_keys, $array_values);
$result = $callback($array);
if (!isEndValue($array_keys, $array[0])) {
$result = array_merge($result, _array_combine($array_keys, $array_values, $callback));
}
return $result;
}
$callback = function($array1) {
return [$array1[0] => $array1[1]];
};
$c = _array_combine($a, $b, $callback);
print_r($c);
ここでは、そこまで詳しく説明する部分は無いのですが、コールバック関数を作成し引数に追加してあげます。
正直、ここまでくるとあんまり使っている意味が無くなってくると思うのですが、この自作関数にPHPの沢山の機能を詰め込むことが出来るので出来た時の達成感はあります(笑)
最後に
いかがだったでしょうか、どんどん自分で制約を決めていくとさらに厳しくなっていきます。例えば、PHPにある組込みの関数を一切使わずに自作関数だけて実装してみるとかです。大変なのですがめちゃくちゃ楽しく出来ると思うので是非やってみて下さい。