下記のようにJSONデータが2つあるとします。
JSON_A [ { 'id' : '1', 'name' : 'one', 'age' : '18', 'sex' : 'm' }, { 'id' : '2', 'name' : 'two', 'age' : '20', 'sex' : 'f' }, { 'id' : '6', 'name' : 'six', 'age' : '5', 'sex' : 'f' } ]
JSON_B [ { 'id' : '2', 'name' : 'two', 'age' : '20', }, { 'id' : '1', 'name' : 'one', 'age' : '18', 'sex' : 'm' }, { 'id' : '3', 'name' : 'three', 'age' : '60', 'sex' : 'm' } ]
結果として、下記を取得したいです
{ 'id' : '2', 'name' : 'two', 'age' : '20', }, { 'id' : '3', 'name' : 'three', 'age' : '60', 'sex' : 'm' }
要件としては
- idをキーにして、データの重複を判定する
- データの入っている順番は保証されない
- JSON_Aから完全に重複するデータを削除し、差分のあるデータのみをJSON_Bから抽出したい
ex1) 下記は完全一致
A [{id=1,z=1,X=1},{id=2,z=2,x=2},{id=3,z=3,X=3}]
B [{id=3,z=3,X=3},{id=2,z=2,x=2},{id=1,z=1,X=1}]
ex2) 下記はid=1以外不一致
A [{id=1,z=1,X=1},{id=2,z=2,x=2},{id=3,z=3,X=3}]
B [{id=3,z=3},{id=2,z=222,x=222},{id=1,z=1,X=1},{id=4,z=4,x=4,c=4]
自分で考えてみたのですが、
- JSON_AとJSON_Bを配列にデコード
- 2つの配列をループ、その中で更にハッシュをループさせながらkeyとvalueを1つずつ比較する
- 差分があるハッシュを配列にpushする
という感じで、ネストが深くあまりスマートでないのでスッキリ書く方法があれば教えて下さい。
追記:
自分が書いたコードです…。
aとbはJSONデコード済みと見て下さい。
my $diff_data; my $diff_flag = 0; my $id_match_flag = 0; foreach my $b_data (@$b) { foreach my $a_data (@$a) { if ($b_data->{'id'} eq $a_data->{'id'}) { $id_match_flag = 1; if (keys(%$b_data) ne keys(%$a_data)) { push @$diff_data, $b_data; } else { foreach my $key (keys(%$b_data)){ unless ($b_data->{$key} eq $a_data->{$key}) { $diff_flag = 1; } } } if ($diff_flag) { push @$diff_data, $b_data; $diff_flag = 0; } } } unless ($id_match_flag) { push @$diff_data, $b_data; } $id_match_flag = 0; }
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。