I have two multidimensional arrays that consist of arrays and objects.
$new = [
'a' => 'b',
'c' => (object)[
'd' => [1 => 11, 2 => 12],
'f' => 'Hello',
],
];
$old = [
'a' => 'b',
'c' => (object) [
'd' => [1 => 11, 2 => 22],
'f' => 'Goodbye',
],
];
I'm trying to find differences between these two arrays by using below function, but the result seems wrong when two objects are compared together. How can I change this function to get correct output?
function compare($array1, $array2)
{
$result = array();
foreach ($array1 as $key => $value) {
if (is_array($value)) {
if (array_key_exists($key, $array2)) {
$recursiveArrayDiff = compare($value, $array2[$key]);
if (count($recursiveArrayDiff)) {
$result[$key] = $recursiveArrayDiff;
}
continue;
}
else {
$result[$key] = $value;
continue;
}
}
if (is_object($value)) {
if (isset($key, $array2) && is_object($array2[$key])) {
$props = array_keys(get_object_vars($value));
foreach ($props as $prop) {
if (isset($array2[$key]->{$prop})) {
if (is_object($value->{$prop}) && is_object($array2[$key]->{$prop})) {
$temp = compare($value->{$prop}, $array2[$key]->{$prop});
if (count($temp)) {
$result[$key] = array($prop => $temp);
}
continue;
} elseif (is_array($value->{$prop}) && is_array($array2[$key]->{$prop})) {
$temp = compare($value->{$prop}, $array2[$key]->{$prop});
if (count($temp)) {
$result[$key] = array($prop => $temp);
}
continue;
} else {
if ($value->{$prop} != $array2[$key]->{$prop}) {
$result[$key] = array($prop => $value->{$prop});
}
}
} else {
$result[$key] = array($prop => $value->{$prop});
}
}
}
}
if ($value != $array2[$key]) {
$result[$key] = $value;
}
}
return $result;
}
The correct and wrong outputs are as follows:
//correct output
Array
(
[c] => stdClass Object
(
[d] => Array
(
[2] => 12
)
[f] => Hello
)
)
//wrong output
Array
(
[c] => stdClass Object
(
[d] => Array
(
[1] => 11
[2] => 12
)
[f] => Hello
)
)
Related
I have an array like below, as you can see the last array [adad] value is blank, how can I write an if statement to tell whether this is blank.
Array
(
[K] => Array
(
[0] => mabel__chan
[1] => mabel chan
)
[B] => Array
(
[0] => kieron br
)
[C] => Array
(
[0] => a br
[1] => a
)
[adad] => Array
(
[0] =>
)
)
I have tried doing this
if (count(array_filter($array)) == 0) {}
Pseudo code
if(array[key] == blank) {
echo "is blank";
} else {
echo "isn't blank";
}
**PHP Script this is how I get my data from mongoDB*
The answer below is working correctly when I use echos but now when I'm trying to push into new arrays its broken somewhere I get no data back anymore.
$col = "A" . $user->agencyID;
$db = $m->rules;
$collection = $db->$col;
$id = $_POST['ruleID'];
$search = array(
'_id' => new MongoId($id)
);
$cursor = $collection->find($search);
$validTagsArray = array();
$validArray = array();
foreach ($cursor as $key => $value) {
$temp = array_walk($array, function($v, $k) {
if (count(array_filter($v)) === 0) {
foreach ($value['AutoFix'] as $keyTwo => $valTwo) {
$x = 0;
$validTagsArray['data'][] = array($keyTwo, $x);
}
} else {
foreach ($value['AutoFix'] as $keyTwo => $valTwo) {
$x = 0;
foreach ($valTwo as $key => $value) {
$x++;
}
$validTagsArray['data'][] = array($keyTwo, $x);
}
}
});
}
echo json_encode($validTagsArray);
You can try this -
$array = array
(
'K' => array('0' => 'mabel__chan','1' => 'mabel chan'),
'B' => array('0' => 'kieron br'),
'C' => array('0' => 'a br', '1' => 'a'),
'adad' => array('0' => '')
);
$temp = array_walk($array, function($v, $k) {
if(count(array_filter($v)) === 0) { // check the count of non-empty elements in the sub array
echo $k . ' is empty';
}
});
Output
adad is empty
You can write as:
if([adad][0]== " ")
{
}
You can also try this :
foreach($array as $key=>$value){
if(empty($value))
echo "empty";
}
I have the following array:
Array
(
[0] => Array
(
[dest_in_id] => 1
[dest_user_id] => 37251
[dest_inv_user_id] => 37247
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[1] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
[2] => Array
(
[dest_in_id] => 2
[dest_user_id] => 37251
[dest_inv_user_id] => 37257
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[3] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
)
Need to review the difference in Timestamp each array and if it <= day (86400), then create an array type:
Array
(
[1387168510] => Array
(
[0] => Array
(
[dest_in_id] => 1
[dest_user_id] => 37251
[dest_inv_user_id] => 37247
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
[1] => Array
(
[dest_in_id] => 2
[dest_user_id] => 37251
[dest_inv_user_id] => 37257
[dest_timestamp] => 1387168510
[dest_destination_id] => 64
)
)
[1345220045] => Array
(
[0] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
[1] => Array
(
[gi_in_id] => 3
[gi_user_id] => 37251
[gi_inv_user_id] => 14564
[gi_timestamp] => 1345220045
[gi_group_id] => 2
)
)
)
Important note! Keys may be different!
At once appealed to the function usort. Wanted to do something like this:
usort($aInvitesRows, function($a, $b) {
$akey = array_keys($a);
$bkey = array_keys($b);
if (($b[preg_grep("/(.*?)_timestamp/", $bkey)[3]] - $a[preg_grep("/(.*?)_timestamp/", $akey)[3]]) <= 86400) {
return $b[preg_grep("/(.*?)_timestamp/", $bkey)[3]] = array($a, $b);
}
});
Success of this venture was not crowned :(
At this stage, using usort could only sort by Timestamp (*), what do you do - do not know the, address for the help!
*
usort($aInvitesRows, function($a, $b) {
$akey = array_keys($a);
$bkey = array_keys($b);
return strcmp($b[preg_grep("/(.*?)_timestamp/", $bkey)[3]], $a[preg_grep("/(.*?)_timestamp/", $akey)[3]]);
});
function msort($array, $key, $sort_flags = SORT_REGULAR) {
if (is_array($array) && count($array) > 0) {
if (!empty($key)) {
$mapping = array();
foreach ($array as $k => $v) {
$sort_key = '';
if (!is_array($key)) {
$sort_key = $v[$key];
} else {
// #TODO This should be fixed, now it will be sorted as string
foreach ($key as $key_key) {
$sort_key .= $v[$key_key];
}
$sort_flags = SORT_STRING;
}
$mapping[$k] = $sort_key;
}
asort($mapping, $sort_flags);
$sorted = array();
foreach ($mapping as $k => $v) {
$sorted[] = $array[$k];
}
return $sorted;
}
}
return $array;
}
$arr = $aInvitesRows;
$result = array();
$item = array_shift($arr);
$akeys = array_keys($item);
$dt = new \DateTime();
$dt->setTimestamp($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]);
$dt->setTime(0, 0, 0);
$result[$dt->getTimestamp()] = array($item);
foreach ($arr as $item) {
$akeys = array_keys($item);
$f = false;
foreach ($result as $day => $items) {
$diff = ($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]) - $day;
if ($diff < 86400 && $diff > 0) {
$result[$day][] = $item;
$f = true;
break 1;
}
}
if (!$f) {
$dt = new \DateTime();
$dt->setTimestamp($item[preg_grep("/(.*?)_timestamp/", $akeys)[3]]);
$dt->setTime(0, 0, 0);
$result[$dt->getTimestamp()] = array($item);
}
}
I'm trying to group airlines with relations into single chains.
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
)
[1] => Array
(
[0] => Alitalia
[1] => Lufthansa
)
[2] => Array
(
[0] => Transaero
[1] => United
)
[3] => Array
(
[0] => United
[1] => Alitalia
)
[4] => Array
(
[0] => Volotea
[1] => Iberia
)
[5] => Array
(
[0] => Transaero
[1] => Aeroflot
)
)
From that array I need to find connections between elements and combine it to groups. Expected results:
Array
(
[0] => Array
(
[0] => Aeroflot
[1] => S7
[2] => Transaero
[3] => United
[4] => Alitalia
[5] => Lufthansa
)
[1] => Array
(
[0] => Volotea
[1] => Iberia
)
)
Can anyone help with that? I've tried a dozen of ways but still get no success.
The most closest way I've tried which works but not in all cases:
function array_searchRecursive($needle,$haystack) {
foreach($haystack as $key=>$value) {
$current_key=$key;
if($needle===$value OR (is_array($value) && array_searchRecursive($needle,$value) !== false)) {
return $current_key;
}
}
return false;
}
foreach ($newarr as $key => $airlines)
{
foreach ($airlines as $lastkey => $airline)
{
$index = array_searchRecursive($airline,$newarr);
echo $airline.$index."\n";
if ($index !== false)
{
$newarr[$index] = array_merge($newarr[$index],$airlines);
$lastarr[] = $index;
}
}
}
But it doesn't match all values in array.
Recursive function will help you. You are welcome )
$arr = array(
array('Aeroflot','S7','Transaero'),
array('Alitalia','Lufthansa'),
array('Transaero','United'),
array('United','Alitalia'),
array('Volotea','Iberia'),
array('Transaero','Aeroflot')
);
function getConnections($arr,$curr_line_n=0,$num=0) {
for($i=0;$i<count($arr[$curr_line_n]);$i++) {
$cur_air_name = $arr[$curr_line_n][$i];
for($k=$curr_line_n+1; $k<count($arr); $k++) {
for($l=0;$l<count($arr[$k]);$l++) {
if ($arr[$k][$l]==$cur_air_name) {
$arr[$curr_line_n] = array_values(array_unique(array_merge($arr[$curr_line_n],$arr[$k])));
array_splice($arr,$k,1);
$num++;
$arr = getConnections($arr,$curr_line_n,$num);
}
}
}
}
$num++;
$curr_line_n++;
if ($curr_line_n!=count($arr)) {
$arr = getConnections($arr,$curr_line_n,$num);
}
return $arr;
}
print_r(getConnections($arr));
As per your example you are just grouping sub arrays by taking first sub array as reference. for example if you have any elements common in first sub array and in subsequent sub arrays then you combine them into one sub array.
<?php
$arr = array(
array('a', 'b', 'c', 'd'),
array('d', 't'),
array('t', 'f'),
array('k', 'o'),
array('p', 'z')
);
$arr_implode = array();
foreach ($arr as $key => $value) {
if (is_array($value)) {
$arr_implode[$key] = implode('', $value);
} else {
$arr_implode[$key] = $value;
}
}
$arr_key = array();
$result = array();
$count = count($arr_implode);
$tempj = 0;
for ($i = 0; $i <= $count; $i++) {
$flag = FALSE;
for ($j = ($i + 1); $j < $count; $j++) {
similar_text($arr_implode[$i], $arr_implode[$j], $percent);
if ($percent > 0) {
$result[] = array_merge($arr[$i],$arr[$j]);
break;
} else {
$result[] = $arr[$j];
break;
}
}
}
foreach($result as $key => $val){
$result[$key] = array_unique($val);
}
echo "<pre>";
print_r($result);
echo "</pre>";
?>
Try this code.
$arr = [
['Aeroflot', 'S7', 'Transaero'],
['Alitalia', 'Lufthansa'],
['Transaero', 'United'],
['United', 'Alitalia'],
['Volotea', 'Iberia'],
['Transaero', 'Aeroflot']
];
$hash = [];
$result = [];
foreach($arr as $set){
foreach($set as $el){
if(!$hash[$el]) $hash[$el] = [] ;
$hash[$el] = array_merge($hash[$el], $set);
}
}
function merge_connections(&$h, $key){
if(!$h[$key]) return [];
$data = [$key];
$rels = $h[$key];
unset($h[$key]);
foreach($rels as $rel){
if($rel==$key) continue;
$data = array_merge($data, merge_connections($h, $rel));
}
return $data;
}
foreach(array_keys($hash) as $company){
if(!$hash[$company]) continue;
array_push($result, merge_connections($hash, $company));
}
print_r($result);
I have this two arrays:
$arr1['product_detail'] = array(
"26" => array("Blue", "Green"),
"28" => array("S")
);
$arr2['variation'] = array(
"pupc" => array("123456", "654321"),
"pprice" => array(1, 2),
"pqty" => array(10, 11)
);
I need to build a new array containing values based on position, less said:
$arr3 = array(
array("Blue", "S", "123456", 1, 10),
array("Green", "S", "654321", 2, 11)
);
If you notice I mix all the position of both original arrays. I think in something like:
foreach ($arr2 as $key => $value) {
foreach ($value as $key1 => $value1) {
foreach ($value1 as $key2 => $value2) {
foreach ($arr1 as $key3 => $value3) {
echo $key3;
}
}
}
}
But it's very ugly and I think is better ways to do this, any help?
It is good idea to use a function
function array_addition($main_array, $new_array) {
foreach ($new_array as $aItem) {
for ($i=0;$i<=1;$i++) {
$main_array[$i][] = current($aItem) ? current($aItem) : reset($aItem);
next($aItem);
}
}
return $main_array;
}
$arr3 = array();
$arr3 = array_addition($arr3, $arr1['product_detail']);
$arr3 = array_addition($arr3, $arr2['variation']);
$arr1['product_detail'] = array(
"26" => array("Blue", "Green"),
"28" => array("S")
);
$arr2['variation'] = array(
"pupc" => array("123456", "654321"),
"pprice" => array(1, 2),
"pqty" => array(10, 11)
);
function convert_array_index_name_to_number($arr)
{
$temp_ar = array();
foreach($arr as $key=>$val)
{
if(is_array($val))
{
$val = convert_array_index_name_to_number($val);
}
$temp_ar[] = $val;
}
return $temp_ar;
}
$arr1 = convert_array_index_name_to_number($arr1);
$arr2 = convert_array_index_name_to_number($arr2);
$arr3 = array();
for($i=0; $i<$count_of_variations; $i++)
{
$temp_arr = array();
$temp_arr[] = $arr1[0][0][$i];
$temp_arr[] = $arr1[0][1][0];
foreach($arr2[0] as $key => $value)
{
$temp_arr[] = $value[$i];
}
$arr3[] = $temp_arr;
}
Result
Array
(
[0] => Array
(
[0] => Blue
[1] => S
[2] => 123456
[3] => 1
[4] => 10
)
[1] => Array
(
[0] => Green
[1] => S
[2] => 654321
[3] => 2
[4] => 11
)
)
I have 2 arrays
Array
(
[010156] => Array
(
[supp_number] => 010156
[totalamount] => 4.113,23
[debtorcred] => H
[amount1] => 4.113,23-
[amount2] =>
[amount3] =>
[amount4] =>
[amount5] =>
[amount6] =>
)
)
Array
(
[010156] => Array
(
[supp_number] => 010156
[totalamount] => 4.113,23
[debtorcred] => H
[amount1] => 4.113,23-
[amount2] =>
[amount3] =>
[amount4] =>
[amount5] =>
[amount6] =>
)
)
Is it possible that I can combine these separate arrays into one and add the values together so that the outcome will be:
Array
(
[010156] => Array
(
[supp_number] => <<<TOTAL >>>
[totalamount] => <<<TOTAL >>>
[debtorcred] => <<<TOTAL >>>
[amount1] => <<<TOTAL >>>
[amount2] => <<<TOTAL >>>
[amount3] => <<<TOTAL >>>
[amount4] => <<<TOTAL >>>
[amount5] => <<<TOTAL >>>
[amount6] => <<<TOTAL >>>
)
)
This is the function I have at the moment but I cannot seem to make it work:
function array_merge_numeric_values()
{
$arrays = func_get_args();
$merged = array();
foreach ($arrays as $array)
{
foreach ($array as $key => $value)
{
if ( ! isset($merged[$key]))
{
$merged[$key] = $value;
}
else
{
$merged[$key] += $value;
}
}
}
This actual calculation can be done in 2 lines of code, no need for loops:
http://codepad.viper-7.com/ieSkHQ
$arr1 = array('amount1' => 1, 'amount2' => 6);
$arr2 = array('amount1' => 2, 'amount2' => 7);
$add = function($a, $b) { return $a + $b; };
$summedArray = array_map($add, $arr1, $arr2);
print_r($summedArray);
Youl'll just need to make the appropriate adjustment to account for you nested structure.
Create a new empty array and loop in the first array as following:
$array1 = array('my_num' => 10, 'my_num2' => 20);
$array2 = array('my_num' => 15, 'my_num2' => 25);
$newArray = array();
foreach($array1 as $key => $value){
if(isset($array2[$key])){
$newArray[$key] = $value+$array2[$key];
} else {
$newArray[$key] = $value;
}
}
print_r($newArray);
$value in your case is an array, not a value. You can try this:
function array_merge_numeric_values()
{
$arrays = func_get_args();
$merged = array();
foreach ($arrays as $array)
{
foreach ($array as $key => $value)
{
if(!isset($merged[$key]))
{
$merged[$key] = array();
}
foreach($value as $kk => $vv)
{
if ( ! isset($merged[$key][$kk]))
{
$merged[$key][$kk] = $vv;
}
else
{
$merged[$key][$kk] += $vv;
}
}
}
}
}