PHP での 2 次元連想配列交差のデモ
コード:
<?php
function compare_states($a1, $a2){
$diff1 = strcasecmp($a1['state_id'], $a2['state_id']);
$diff2 = strcasecmp($a1['state_name'], $a2['state_name']);
if ($diff1 != 0) return $diff1;
if ($diff2 != 0) return $diff2;
return 0;
}
function calculate_intersection($a1, $a2){
return array_uintersect($a1, $a2, 'compare_states');
}
?>
実行方法:
<?php
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print_r($a);
//in this simple case, the intersection is equivalent to $a.
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>14, "state_name"=>"Foobar"));
$new = calculate_intersection($a, $b);
print_r($a);
//in this case, the intersection is empty.
?>
上記のコードが設計どおりに機能することを証明する単体テスト:
$a = Array();
$b = Array();
$new = calculate_intersection($a, $b);
print "\nGroup1\n";
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>14, "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup2\n";
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14 ? "." : "FAIL"));
print (($new[0]['state_name'] == "Illinois" ? "." : "FAIL"));
//==============================================
print "\nGroup3\n";
$a = Array(Array("state_id"=>14, "state_name"=>"Illinois"), Array("state_id"=> "22", "state_name"=>"Massachusetts"));
$b = Array(Array("state_id"=>14, "state_name"=>"Illinois"), Array("state_id"=> "22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print ((count($new) == count($a) && count($a) == count($b)) ? "." : "FAIL");
print (($new[0]['state_id'] == 14 ? "." : "FAIL"));
print (($new[0]['state_name'] == "Illinois" ? "." : "FAIL"));
print (($new[1]['state_id'] == 22 ? "." : "FAIL"));
print (($new[1]['state_name'] == "Massachusetts" ? "." : "FAIL"));
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print "\nGroup5\n";
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$new = calculate_intersection($a, $b);
print "\nGroup6\n";
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup7\n";
print ((count($new) == 1) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Fromulate"));
$new = calculate_intersection($a, $b);
print "\nGroup8\n";
print ((count($new) == 0) ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$b = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup9\n";
print ((count($new) == 2) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
print (($new[1]['state_id'] == 14) ? "." : "FAIL");
print (($new[1]['state_name'] == "Illinois") ? "." : "FAIL");
//==============================================
$a = Array(Array("state_id"=>"14", "state_name"=>"Illinois"), Array("state_id"=>"22", "state_name"=>"Massachusetts"));
$b = Array(Array("state_id"=>"22", "state_name"=>"Massachusetts"), Array("state_id"=>"14", "state_name"=>"Illinois"));
$new = calculate_intersection($a, $b);
print "\nGroup7\n";
print ((count($new) == 2) ? "." : "FAIL");
print (($new[0]['state_id'] == 14) ? "." : "FAIL");
print (($new[0]['state_name'] == "Illinois") ? "." : "FAIL");
print (($new[1]['state_id'] == 22) ? "." : "FAIL");
print (($new[1]['state_name'] == "Massachusetts") ? "." : "FAIL");
?>
上記のコードは次を出力します。
eric@dev $ php a.php
Group1
..
Group2
....
Group3
.....
Group5
.
Group6
...
Group7
...
Group8
.
Group9
.....
Group7
.....
すべてのドットは、すべてが通過したことを意味します。
このコードはどのようなケースを処理しますか?
- 両方の配列が空です。交差点は空です。
- 1つは空で、もう1つはアイテムがあります。交差点は空です。
- 両方の配列には、set: 1 と set: n という同一の項目があります。Intersection は最初の配列に相当します。
- 両方の配列は、シャッフルされていることを除いて同一です。Intersection は最初の配列に相当します。
- state_name がそれぞれの場合で異なり、state_id が同じであることを除いて、配列は同じです。交差点は空です。
- 配列 a には、b とは異なる項目、B と共通の項目があります。配列 b は、a とは異なる項目と A に共通の項目があります。交差は、a と b の両方に共通する項目です。
しないこと:
null/未定義/異なる深さの配列や、2 層以上の深さの配列はテストされません。文字列を int と比較したり、float を 8 進数と比較したりしてデータ型が交換されると、おそらく失敗します。PHP に平等を正しく行わせるのは困難です。http://eev.ee/blog/2012/04/09/php-a-fractal-of-bad-design/
データベースでこの作業を行うためにできる限りのことを行います。PHP で行うと、失敗したクジラを召喚するためにクラクションが鳴ります。非効率なので、数百以上の項目を操作しない方がよいでしょう。予想外のケースで左ジャブを驚かせるでしょう。ボンネットの下で何をしているのかを読んだり理解したりするのはちょっと難しいです。