PHP5.2.6において

配列A
Array
(
[11318] => 63705
[11549] => 20522
[12315] => 233151
[19999] => 51
)
配列B
Array
(
[11318] => 63700
[11549] => 20644
[12315] => 233100
[12316] => 999
)

上の2個の配列を比較して、引き算をしたいと思います。
マッチしたものは引いて
配列C
Array
(
[11318] => 5
[11549] => -122
[12315] => 51
)
などと格納して、マッチしないものはそのまま
配列D
Array
(
[19999] => 51
[12316] => 999
)
という風に、配列CとDを作成したのですが何かいい方法はありませんか?

回答の条件
  • 1人5回まで
  • 登録:
  • 終了:2009/02/10 11:40:03
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

回答7件)

id:inokuni No.1

回答回数1343ベストアンサー獲得回数21

ポイント20pt

PHPソース

<?php

$a = array(
	"11318" => 63705,
	"11549" => 20522,
	"12315" => 233151,
	"19999" => 51
);

$b = array(
	"11318" => 63700,
	"11549" => 20644,
	"12315" => 233100,
	"12316" => 999,
);

$c = array();
$d = array();
foreach($a AS $akey => $avalue){
	if(!empty($b[$akey])){
		$c[$akey] = $a[$akey] - $b[$akey];
	}else{
		$d[$akey] = $a[$akey];
	}
}
foreach($b AS $bkey => $bvalue){
	if(empty($a[$bkey])){
		$d[$bkey] = $b[$bkey];
	}
}

echo '$c = '.print_r($c, true);
echo '$d = '.print_r($d, true);

?>

実行結果:

$c = Array
(
    [11318] => 5
    [11549] => -122
    [12315] => 51
)
$d = Array
(
    [19999] => 51
    [12316] => 999
)
id:hopefully

ありがとうございます。

やはり。foreachでまわして処理しかないんすかね?

なんか関数とかではさくっとはいきそうもないですかね?

2009/02/03 12:48:27
id:pahoo No.2

回答回数5960ベストアンサー獲得回数633

ポイント20pt

こんな感じでいかがでしょうか。

<?php
$a = array(11318 => 63705, 11549 => 20522, 12315 => 233151, 19999 => 51);
$b = array(11318 => 63700, 11549 => 20644, 12315 => 233100, 12316 => 999);
$c = array();
$d = array();

//$aの要素のうち$bの要素に合致するものを検索し、見つかったら減算する
foreach ($a as $key=>$val) {
    if (isset($b[$key])) {      //合致
        $c[$key] = $a[$key] - $b[$key];
    } else {                    //合致せず
        $d[$key] = $a[$key];
    }
}

//$bの要素のうち$aの要素に合致しないものを検索し、$dに代入する
foreach ($b as $key=>$val) {
    if (! isset($a[$key])) {     //合致せず
        $d[$key] = $b[$key];
    }
}

//結果の確認
print_r($c);
echo '<br />';
print_r($d);
?>
id:hopefully

ありがとうございます。

2009/02/03 15:17:37
id:inokuni No.3

回答回数1343ベストアンサー獲得回数21

ポイント20pt

関数が無ければ作ればいいかと思います。

<?php
function myfunction($a, $b){
	$c = array();
	$d = array();

	foreach($a AS $akey => $avalue){
		if(!empty($b[$akey])){
			$c[$akey] = $a[$akey] - $b[$akey];
		}else{
			$d[$akey] = $a[$akey];
		}
	}
	foreach($b AS $bkey => $bvalue){
		if(empty($a[$bkey])){
			$d[$bkey] = $b[$bkey];
		}
	}
	return array($c, $d);
}

$a = array(
	"11318" => 63705,
	"11549" => 20522,
	"12315" => 233151,
	"19999" => 51
);

$b = array(
	"11318" => 63700,
	"11549" => 20644,
	"12315" => 233100,
	"12316" => 999,
);

list($c, $d) = myfunction($a, $b);

echo '$c = '.print_r($c, true);
echo '$d = '.print_r($d, true);

?>

実行結果

$c = Array
(
    [11318] => 5
    [11549] => -122
    [12315] => 51
)
$d = Array
(
    [19999] => 51
    [12316] => 999
)
id:hopefully

ありがとうございます。

2009/02/03 15:17:29
id:pahoo No.4

回答回数5960ベストアンサー獲得回数633

ポイント20pt

やはり。foreachでまわして処理しかないんすかね?

なんか関数とかではさくっとはいきそうもないですかね?

foreach を使わない方法です(PHP5.0以上)――。

<?php
//配列AからBを減ずるための関数
function mycomp(&$item, $key) {
    global $a, $b;
    $item = $a[$key] - $b[$key];
}

//初期値
$a = array(11318 => 63705, 11549 => 20522, 12315 => 233151, 19999 => 51);
$b = array(11318 => 63700, 11549 => 20644, 12315 => 233100, 12316 => 999);
$c = array();
$d = array();

//配列 $a の中で $b に合致するものに対して減算処理する
$c = array_intersect_key($a, $b);  //一致する要素を$cに代入
array_walk($c, mycomp);            //一致する要素すべてに対して減算処理を行う

//互いに存在しない要素を $d に代入
$d = array_diff_key($a, $b) + array_diff_key($b, $a);

//結果の確認
echo '$c = ';
print_r($c);
echo '<br />';
echo '$d = ';
print_r($d);
?>
id:hopefully

これはいいですねーー。

ありがとうございます。

ひとつだけ質問なのですが

PHPをCLASSで作成している際に

array_walk($c, array($this, "mycomp")); //一致する要素すべてに対して減算処理を行う

という修正をしたのですが

動きませんでした。

どうしたらいいのでそうか?

2009/02/03 15:17:05
id:pahoo No.5

回答回数5960ベストアンサー獲得回数633

ポイント20pt

PHPをCLASSで作成している際に

array_walk($c, array($this, "mycomp")); //一致する要素すべてに対して減算処理を行うという修正をしたのですが動きませんでした。

どんなクラスを作られたのか分かりませんが、array_walkの第二引数はコールバック関数名でなければなりません。そこで、create_function関数を使う必要があります。

たとえば#4で紹介したユーザー関数 mycomp を埋め込むのであれば、下記のように書きます。

array_walk($c, create_function(
    '&$item, $key',
    'global $a, $b; $item = $a[$key] - $b[$key];'
));

質問者が未読の回答一覧

 回答者回答受取ベストアンサー回答時間
1 GoldenDawn 426 399 81 2009-02-03 12:48:52
2 sakai 9 8 2 2009-02-03 13:30:26

コメントはまだありません

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません