はじめに
リファレンスマニュアルを見ていると「機能は分かるけど、いったい何に使うのかピンとこない」ってことはないですか?そうするとなかなか頭に入らないですよね。この記事では array_reduce() 関数の「使いどころ」の一例として、メールアドレスを一意にする処理を考えます。
※ そんな「使いどころ」的な記事が増えるといいな、とも思います。
免責
「array_reduce() の使いどころ」と題していますが、こんな使い方ばかりではありませんでしょうし、むしろ邪道である可能性もあります。このような記事を鵜呑みにしてはいけません。また、このスニペットを引用して上司に怒られても、あなたの書いたプログラムの正当性をこの記事が保証するわけでもありません。
使いどころ
システムからメールを送信することは、よくあります。
問題になるのは、いつ、どんな場面で誰に送るのか、ということが結構複雑に決まることです。To に対して設定するアドレス、C.C. に対して設定するアドレス、部署、担当プロジェクト、取得元(システムの内部のデータベースから取得するのか、全社統一データベースから API を用いて取得するのかなど)考えることはたくさんあります。
全部を単純に結合すると重複が出ることがあります。重複を排除したい場合も「To に設定したアドレスは C.C. には設定しない」といった配慮が必要なので、単純に array_unique() は採用できません。欲しいのは、複数の配列からの重複排除です。
※ 全部を単純に結合して送信したとしても大して不都合が出るわけでもありません。そうして問題が出ないならそれでもいいでしょう。ですが世の中にはそういうことを気にする人も少なからず居ます。
スニペット
このスニペットは、すでに変数 $to_addr
と $cc_addr
にカンマ区切り文字列のメールアドレスが設定済みで、そこから重複を排除したい場合のコード例です。
// 入力(banana さんが重複)
$to_addr = ['apple@example.com' , 'banana@example.com' , 'citrus@example.com'];
$cc_addr = ['banana@example.com' , 'durian@example.com' , 'elderberry@example.com'];
$addressUniqueFilter = function ($carry, $addr) {
static $allAddressArray = array();
if (is_null($carry) || !is_array($carry)) {
$carry = [];
}
$addr = trim($addr);
if (!in_array($addr, $allAddressArray)) {
$carry[] = $addr;
$allAddressArray[] = $addr;
}
return $carry;
};
$toAddressArray = array_reduce($to_addr, $addressUniqueFilter);
$ccAddressArray = array_reduce($cc_addr, $addressUniqueFilter);
var_dump($toAddressArray);
var_dump($ccAddressArray);
/*
出力:
array(3) {
[0] =>
string(17) "apple@example.com"
[1] =>
string(18) "banana@example.com"
[2] =>
string(18) "citrus@example.com"
}
array(2) {
[0] =>
string(18) "durian@example.com"
[1] =>
string(22) "elderberry@example.com"
}
*/