calculate the difference between two array - php

In PHP, how can I compare two array and get result in a third array ?
This result must contain old and new values. The goal is to display an HTML table with a header like "field | old value | new value" as this, the user can compare all values one by one.
First array :
$array1 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
Second array :
$array2 = array(
'key1' => array(
'key1.1' => 'value',
'key1.2' => 'value',
),
'key2' => array(
'key2.1' => 'value',
'key2.2' => 'value',
),
'key3' => array(
array('key3.1' => 'value'),
array('key3.2' => 'value'),
),
);
What I expect :
$results = array(
'key1' => array(
'key1.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key1.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key2' => array(
'key2.1' => array(
'old' => 'old_value',
'new' => 'new_value',
),
'key2.2' => array(
'old' => 'old_value',
'new' => 'new_value',
),
),
'key3' => array(
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value')
),
array(
'key3.1' => array(
'old' => 'old_value',
'new' => 'new_value'),
)
),
);
What I have already tried without success :
function array_diff_assoc_recursive($array1, $array2) {
$exclude = array(
'custom_key'
);
$difference = array();
foreach($array1 as $key => $value) {
if(is_array($value)){
if( !isset($array2[$key]) || !is_array($array2[$key]) ) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
} else {
$new_diff = array_diff_assoc_recursive($value, $array2[$key]);
if(!empty($new_diff))
$difference[$key] = $new_diff;
}
} else if(!array_key_exists($key,$array2) || $array2[$key] !== $value) {
if(!in_array($key,$exclude)){
$difference[$key]['old'] = $value;
$difference[$key]['new'] = $array2[$key];
}
}
}
return $difference;
}

try this code, i'm sure this will work for you
<?php
echo "<pre>";
$array1 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'xxx',
'key1.3' => 'vvv',
),
'key2' => array(
'key2.1' => 'eee',
'key2.2' => 'fff',
'key2.3' => 'ggg',
),
) ;
echo "Array 1: </br>";
print_r($array1);
$array2 = array(
'key1' => array(
'key1.1' => 'aaa',
'key1.2' => 'ddd',
'key1.3' => 'ccc',
),
'key2' => array(
'key2.1' => 'hhh',
'key2.2' => 'fff',
'key2.3' => 'ttt',
),
);
echo "Array 2:</br>";
print_r($array2);
$result='';
foreach($array1 as $key=> $val)
{
foreach($val as $k=> $v)
{
if($v != $array2[$key][$k])
{
$result[$key][$k]['old']= $array2[$key][$k] ;
$result[$key][$k]['new']= $v;
}
}
}
echo "Compared Result: </br>";
echo "<pre>"; print_r($result);
?>
This will Output
Array 1:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => xxx
[key1.3] => vvv
)
[key2] => Array
(
[key2.1] => eee
[key2.2] => fff
[key2.3] => ggg
)
)
Array 2:
Array
(
[key1] => Array
(
[key1.1] => aaa
[key1.2] => ddd
[key1.3] => ccc
)
[key2] => Array
(
[key2.1] => hhh
[key2.2] => fff
[key2.3] => ttt
)
)
Compared Result:
Array
(
[key1] => Array
(
[key1.2] => Array
(
[old] => ddd
[new] => xxx
)
[key1.3] => Array
(
[old] => ccc
[new] => vvv
)
)
[key2] => Array
(
[key2.1] => Array
(
[old] => hhh
[new] => eee
)
[key2.3] => Array
(
[old] => ttt
[new] => ggg
)
)
)

Prepare arrays using array_walk_recursive, and combine them. Please note that the original arrays will be changed
array_walk_recursive($array1, function(&$i) { if(!is_array($i)) $i = array('old'=> $i); });
array_walk_recursive($array2, function(&$i) { if(!is_array($i)) $i = array('new'=> $i); });
print_r(array_merge_recursive($array1, $array2));
demo

Related

Add array to Value

After a $single_array = array_reduce ($new_array, 'array_merge_recursive', array ());
I get this result
array (size=9)
'key1' => string 'value1'
'key2' => string 'value2'
'key3' => string 'value3'
'key7' =>
array
0 => string 'value7'
1 => string 'value13'
'key8' =>
array
0 => string 'value8'
1 => string 'value14'
'key9' =>
array
0 => string 'value9'
1 => string 'value15'
'key19' => string 'value19'
'key20' => string 'value20'
'key21' => string 'value21'
but i would like that
array
'key1' =>
array
0 => string 'value1'
'key2' =>
array
0 => string 'value2'
'key3' =>
array
0 => string 'value3'
'key7' =>
array
0 => string 'value7'
1 => string 'value13'
'key8' =>
array
0 => string 'value8'
1 => string 'value14'
'key9' =>
array
0 => string 'value9'
1 => string 'value15'
'key19' =>
array
0 => string 'value19'
'key20' =>
array
0 => string 'value20'
'key21' =>
array
0 => string 'value21'
It's probably very simple, but I've been blocking for a few hours.
In short, I would like my array_merge_recursive not to add a key only to the same values, but to add an array[0] also to those which were not the same.
EDIT
The code at the start, the goal being to simplify it and knowing that the values generated as well as the order of the structure can be random.
<?php
$array = array(
'sensors' => array(
'0' => array(
'data' => array(
'0' => array(
'key1' => 'value1',
'key2' => 'value2',
'key3' => 'value3',
)
)
),
'1' => array(
'data' => array(
'0' => array(
'key7' => 'value7',
'key8' => 'value8',
'key9' => 'value9',
)
)
),
'2' => array(
'data' => array(
'0' => array(
'key7' => 'value13',
'key8' => 'value14',
'key9' => 'value15',
)
)
),
'3' => array(
'data' => array(
'0' => array(
'key19' => 'value19',
'key20' => 'value20',
'key21' => 'value21',
)
)
)
)
);
$new_array = array();
foreach ($array as $element1) {
foreach ($element1 as $j => $element2) {
foreach ($element2 as $element3) {
foreach ($element3 as $element4) {
$new_array[$j] = $element4;
$single_array = array_reduce($new_array, 'array_merge_recursive', array());
}
}
}
}
var_dump($single_array);
You can use array_walk_recursive on the original array:
$result = [];
array_walk_recursive($array, function ($value, $key) use (&$result) {
$result[$key][] = $value;
});
After running this on the example array you provided, $result will be:
[
'key1' => ['value1'],
'key2' => ['value2'],
'key3' => ['value3'],
'key7' => ['value7', 'value13'],
'key8' => ['value8', 'value14'],
'key9' => ['value9', 'value15'],
'key19' => ['value19'],
'key20' => ['value20'],
'key21' => ['value21']
];
Thank you, I found, I was just confusing in_array and is_array. My bad
$array2 = array();
foreach ($single_array as $key1 => $value1) {
if (is_array($value1)) {
foreach($value1 as $key2 => $value2) {
$array2[$key1][$key2] = $value2;
}
}
else {
$array2[$key1][] = $value1;
}
}
var_dump($array2);

how to display selected from multidimensional array

I have multidimensional array in which two arrays have multiple array and one has single value which are as below:
$array([0] => array(
[0] => array(
['name'] => 'one',
['number'] => 051
),
[1] => array(
['name'] => 'two',
['number'] => 052
)
),
[1] => array(
['name'] => 'three',
['number'] => 053
),
[2] => array(
[0] => array(
['name'] => 'four',
['number'] => 054
),
[1] => array(
['name'] => 'six',
['number'] => 055
)
)
From above array, how can I get result :
[0] = 051, 052.
[1] = 053.
[2] = 054, 055.
Please help, thank you.
Please try below code:
$var = array(
array(
array(
'name' => 'one',
'number' => '051'
),
array(
'name' => 'two',
'number' => '052'
)
),
array(
'name' => 'three',
'number' => '053'
),
array(
array(
'name' => 'four',
'number' => '054'
), array(
'name' => 'six',
'number' => '055'
)
));
$numbers = [];
foreach ($var as $k => $v) {
$num = [];
if(isset($v['number'])){
$num[] = $v['number'];
}
foreach ($v as $k2 => $v2) {
if(isset($v2['number'])){
$num[] = $v2['number'];
}
}
$numbers[$k] = implode(',', $num) . '.';
}

Inserting a new key if a particular key value matches in both the arrays

$array1 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'name' => 'Plate 1'
),
[1] => array(
'id' => 'xyz6378399sjwui39',
'name' => 'Plate 2'
),
[2] => array(
'id' => 'tr2e6378399sjwui39',
'name' => 'Plate 3'
)
)
and another array
$array2 = array(
[0] => array(
'id' => 'gdye6378399sjwui39',
'ETA' => '8'
),
[1] => array(
'id' => 'tr2e6378399sjwui39',
'ETA' => '9'
)
[2] => array(
'id' => 'xyz6378399sjwui39',
'ETA' => '5'
)
)
I want to compare the two arrays. I am doing it like this way:-
if(!empty($array2))
{
foreach($array1 as $ck => $cl)
{
foreach($array12 as $ued){
if($cl['id'] == $ued['id'])
{
$array1[$ck]['ETA'] = $ued['ETA'];
break;
}
}
}
What are the other better ways to do this? The order of the two arrays may vary, and so does the size.
If you index the second array by the id (using array_column()) you can get away without using the inner foreach() and just use isset()...
$match = array_column($array2, null, 'id');
foreach ( $array1 as $ck=>$cl) {
if ( isset($match[$cl['id']]) ) {
$array1[$ck]['ETA'] = $match[$cl['id']]['ETA'];
}
}
print_r($array1);

array_filter with assoc array?

I am using array_filter to do something like this:
function endswithy($value) {
return (substr($value, -1) == 'y');
}
$people = array("Johnny", "Timmy", "Bobby", "Sam", "Tammy", "Danny", "Joe");
$withy = array_filter($people, "endswithy");
var_dump($withy);
BUT with the more option in filter for example
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof"),
"Timmy"=>array("year"=>1989, "job"=>"std"),
"Bobby"=>array("year"=>1988),
"Sam"=>array("year"=>1983),
"Tammy"=>array("year"=>1985),
"Danny"=>array("year"=>1983),
"Joe"=>array("year"=>1989,"job"=>"prof"));
OR
$people = array(
array("name"=>"Johnny","year"=>1989, "job"=>"prof"),
array("name"=>"Timmy","year"=>1989, "job"=>"std"),
array("name"=>"Bobby""year"=>1988),
array("name"=>"Sam","year"=>1983),
array("name"=>"Tammy","year"=>1985),
array("name"="Danny","year"=>1983),
array("name"="Joe","year"=>1989,"job"=>"prof"));
How Can I got the only this people (endwith y and year=1989 and job=prof) ,Can I use array_filter?
or any build-in function to do this?
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof")
);
OR
$people = array(
array("name="Johnny","year"=>1989, "job"=>"prof")
);
PHP 5.6 introduces the optional flag ARRAY_FILTER_USE_KEY that will allow this:
function endswithy($name) {
return (substr($name, -1) == 'y');
}
$people = array(
"Johnny"=>array("year"=>1989, "job"=>"prof"),
"Timmy"=>array("year"=>1989, "job"=>"std"),
"Bobby"=>array("year"=>1988),
"Sam"=>array("year"=>1983),
"Tammy"=>array("year"=>1985),
"Danny"=>array("year"=>1983),
"Joe"=>array("year"=>1989,"job"=>"prof")
);
$peopleEndingInY = array_filter($people, 'endswithy', ARRAY_FILTER_USE_KEY);
// Outputs: 5
var_dump(count($peopleEndingInY));
If you need to maintain and key and the value, another flag ARRAY_FILTER_USE_BOTH will do that as seen in this example:
$ar = array(
'key1' => 'value1',
'key2' => 'value2'
);
//Note that this doens't actually filter anything since it doesn't return a bool.
$output = array_filter($ar, function($value, $key){
echo sprintf("%s => %s\n", $key, $value);
}, ARRAY_FILTER_USE_BOTH);
Either use foreach with your current array's structure:
$people = array(
"Johnny" => array("year" => 1989, "job" => "prof"),
"Timmy" => array("year" => 1989, "job" => "std"),
"Bobby" => array("year" => 1988),
"Sam" => array("year" => 1983),
"Tammy" => array("year" => 1985),
"Danny" => array("year" => 1983),
"Joe" => array("year" => 1989, "job" => "prof"),
);
foreach ( $people as $name => $info ) {
if ( substr($name, -1) !== 'y' || $info['year'] != 1989 ) {
unset($people[$name]);
}
}
print_r($people);
// output:
Array
(
[Johnny] => Array
(
[year] => 1989
[job] => prof
)
[Timmy] => Array
(
[year] => 1989
[job] => std
)
)
Or convert your array so that name is value of inner array:
$people = array(
array('name' => 'Johnny', 'year' => 1989, 'job' => 'prof'),
array('name' => 'Timmy' , 'year' => 1989, 'job' => 'std'),
array('name' => 'Bobby' , 'year' => 1988),
array('name' => 'Sam' , 'year' => 1983),
array('name' => 'Tammy' , 'year' => 1985),
array('name' => 'Danny' , 'year' => 1983),
array('name' => 'Joe' , 'year' => 1989, 'job' => 'prof'),
);
function filter($item) {
return substr($item['name'], -1) === 'y' && $item['year'] == 1989;
}
$filteredPeople = array_filter($people, 'filter');
print_r($filteredPeople);
// output:
Array
(
[0] => Array
(
[name] => Johnny
[year] => 1989
[job] => prof
)
[1] => Array
(
[name] => Timmy
[year] => 1989
[job] => std
)
)

Searching in a multi-dimensional array (PHP)

I'm having a problem lately that's driving me crazy. I have a multi-dimensional array like this:
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
)
'2' => array(
'id' => '3',
'name' => 'test',
'cat' => array(
'a' => '50',
'b' => '40',
'c' => '90'
),
'canvas' => '1'
)
)
);
And i want to search on it using a function like this: search('canvas = 1');
That would return all the arrays, child of db, that have a key canvas with the value of 1. Or, for example:
search('a = 15');
Would return all arrays that have a key, child of cat, named a and with a value of 15.
$a = array(
'db' => array(
'0' => array(
'id' => '1',
'name' => 'test',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
'1' => array(
'id' => '2',
'name' => 'test2',
'cat' => array(
'a' => '15',
'b' => '20',
'c' => '30'
),
'canvas' => '2'
),
)
);
//checks if array $array contains element with $searchKey key, and $searchVal value
function arrayContains($array, $searchVal, $searchKey) {
if (!is_array($array))
return false;
foreach ($array as $key => $value) {
if ($key === $searchKey && $searchVal === $value)
return true;
if (is_array($value) && arrayContains($value, $searchVal, $searchKey))
return true;
}
return false;
}
function search($a, $search) {
list($searchKey, $searchVal) = explode('=', $search);
$result = array();
foreach($a as $val) {
if (arrayContains($val, $searchVal, $searchKey))
$result[] = $val;
}
return $result;
}
print_r(search($a['db'], "a=15"));
print_r(search($a['db'], "canvas=1"));
Which produces this output(outputs sub-arrays of $a['db'] which contain searched key=>value pair):
Array
(
[0] => Array
(
[id] => 1
[name] => test
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
[1] => Array
(
[id] => 2
[name] => test2
[cat] => Array
(
[a] => 15
[b] => 20
[c] => 30
)
[canvas] => 2
)
)
Array
(
[0] => Array
(
[id] => 3
[name] => test
[cat] => Array
(
[a] => 50
[b] => 40
[c] => 90
)
[canvas] => 1
)
)
Just check the below link if this can help you -
http://php.net/manual/en/function.array-search.php
It contains detailed documentation of php function array_search() and various user codes for searching in multi-dimensional array along with user reviews.
function search($array, $canvas)
{
$result = array();
foreach ($array as $k1 => $v1) {
foreach ($v1 as $k2 => $v2) {
if ($v2['canvas'] == $canvas) {
$result[] = $array[$k1][$k2];
}
}
}
return $result;
}
// $a = your array
print_r(search($a, 1));

Categories