kajab
kajab

Reputation: 133

Find associative element changes between two flat arrays and return an array of affected keys with their before and after values

is there a function to compare 2 different associative arrays, and return changes?

For example

$age = array("Peter" => "35", "Ben" => "37", "Joe" => "");
$age2 = array("Peter" => "38", "Ben" => "37", "Joe" => "43");

return

$return = array(
    "Peter" => "Changed from 35 to 38",
    "Joe" => "Changed from blank to 43"
);

Upvotes: 0

Views: 155

Answers (5)

mickmackusa
mickmackusa

Reputation: 48073

Your sample data does not indicate that the second array might contain new keys. With this in mind, just iterate the first array and access the same-keyed element in the second array, compare them, and format the values pushed to the result array. Demo

$before = ["Peter" => "35", "Ben" => "37", "Joe" => ""];
$after = ["Peter" => "38", "Ben" => "37", "Joe" => "43"];

$result = [];
foreach($before as $k => $v) {
    if ($v !== $after[$k]) {
        $result[$k] = sprintf(
            'Changed from "%s" to "%s"',
            htmlspecialchars($v, ENT_QUOTES, 'UTF-8'),
            htmlspecialchars($after[$k], ENT_QUOTES, 'UTF-8')
        );
    }
}
var_export($result);

Output:

array (
  'Peter' => 'Changed from "35" to "38"',
  'Joe' => 'Changed from "" to "43"',
)

Upvotes: 0

Prasanth Bendra
Prasanth Bendra

Reputation: 32820

Check this, more efficient solution :

$age1   = array("Peter"=>"35","Ben"=>"37","Joe"=>"");
$age2   = array("Peter"=>"38","Ben"=>"37","Joe"=>"43");

$result = array_diff_assoc($age1, $age2);

$res    = array();
foreach($result as $key=>$val){
  $res[$key]  = "Changed from ".($val?$val:"Balnk")." to ".($age2[$key]?$age2[$key]:"blank");
}

echo "<pre>";
print_r($res);

Upvotes: 0

Fabian Schmengler
Fabian Schmengler

Reputation: 24576

As pointed out before, array_diff_assoc is your starting point. The rest is building your strings for each difference:

function compareAge($age, $age2)
{
    $return = array();
    foreach(array_keys(array_diff_assoc($age, $age2)) as $diffKey) {
        $from = empty($age[$diffKey]) ? 'blank' : $age[$diffKey];
        $to = empty($age2[$diffKey]) ? 'blank' : $age2[$diffKey];
        $return[$diffKey] = "Changed from {$from} to {$to}";
    }
    return $return;
}

working demo

Upvotes: 2

Hugo Delsing
Hugo Delsing

Reputation: 14173

Nothing default, by I had some time on my hands :) http://codepad.org/2UtrPE3o

<?
$age = array("Peter"=>"35","Ben"=>"37","Joe"=>"");
$age2 = array("Peter"=>"38","Ben"=>"37","Joe"=>"43");

$result = array();
foreach($age as $key=>$val) {
  if (array_key_exists($key, $age2)) {
    if ($val!==$age2[$key])
      $result[$key] = 'Changed from '.(empty($val)?'blank':$val).' to '. (empty($age2[$key])?'blank':$age2[$key]);
  } else {
    $result[$key] = 'Changed from '.(empty($val)?'blank':$val).' to blank';
  }
}

foreach($age2 as $key=>$val) {
  if (!array_key_exists($key, $age)) {
    $result[$key] = 'Changed from blank to ' . $val;
  }
}

var_dump($result);
?>

Upvotes: 1

castis
castis

Reputation: 8223

array_diff may start you on the right path. Although it doesn't give the exact output you're looking for, it will show you the differences between two arrays.

As mark pointed out, array_diff_assoc may be even more helpful as it maintains array indexes.

Upvotes: 5

Related Questions