I have two arrays $users and $find. I need count how many matches in $users if $find array would be changed.
$users = array(
[
'name' => 'Jim',
'sname' => 'Carrey'
],
[
'name' => 'Michael',
'sname' => 'Douglas'
],
[
'name' => 'Michael',
'sname' => 'Jackson'
],
[
'name' => 'Michael',
'sname' => 'Jordan'
]
);
Find array changed dynamically. It may be:
$find = array (
'name' => array('Michael'),
'sname' => array('Douglas', 'Jordan')
);
OR:
$find = array (
'sname' => array('Carrey', 'Jordan')
);
I'm looking for a one-size-fits-all solution for for any values in $find array.
Thanks!
I can count if I have static keys and values in $find array:
$result = array_filter($users, function($user) {
return in_array($user['name'], ['Michael', 'Jim']) && in_array($user['sname'], ['Douglas', 'Jordan', 'Carrey']);
});
$count = count($result);
print_r($result);
But I don't understand how count if it should be dynamic keys and values in $find array.
If you want to deal with an unknown number of items in $find, then you will need to loop over them. The use keyword helps to "inject" $find into your callback function. In your loop, you can return false, if the in_array check for the current find item results in false, otherwise you return true after the loop.
$result = array_filter($users, function($user) use ($find) {
foreach($find as $col => $values) {
if(!in_array($user[$col], $values)) {
return false;
}
}
return true;
});
$result=array_intersect($users,$find);
print_r($result);
I have an array like this:
$array1 = [
[
'Firepack_sn' => '20012205',
'Installation_Date' => '',
'Type' => 'EH',
'Capacity_m3h' => '81',
'Pressure_bar' => '3,4',
'Rpm' => '2930',
'Power_kw' => '72',
],
[
'Firepack_sn' => '20023901',
'Installation_Date' => '',
'Type' => 'DH',
'Capacity_m3h' => '195',
'Pressure_bar' => '4,2',
'Rpm' => '2000',
'Power_kw' => '72',
],
];
And an array2 like this:
$array2 = [
[
'user_id' => '40009',
'firepack_id' => '20012205',
'activated' => '1',
],
[
'user_id' => '40009',
'firepack_id' => '21020393',
'activated' => '0',
],
];
Now I want to filter the first array, so I only get the rows with a Firepack_sn value that exists in array2 as firepack_id.
Desired output:
[
{
"Firepack_sn":"20012205",
"Installation_Date":"",
"Type":"EH","Standard":"VAS",
"Capacity_m3h":"81",
"Pressure_bar":"3,4",
"Rpm":"2930",
"Power_kw":"72"
}
]
How can I achieve this?
Here is a way to do it :
First, you need to extract the firepack_id you need to look for, then you need to loop through $arr1 and check if Firepack_sn is the same than than one of the firepack_id you extracted before, if yes, then you add it to an array.
$arr1 = json_decode('[{"Firepack_sn":"20012205","Installation_Date":"","Type":"EH","Standard":"VAS","Capacity_m3h":"81","Pressure_bar":"3,4","Rpm":"2930","Power_kw":"72","Pump_Type":"KSB KFP50-200","Motor_Type":"DOOSAN PU066 VAS/CEA","Controller_Type":"WB882-E10 VAS","Pump_sn":"085259","Motor_sn":"EARPA209635","Controller_sn":"","Servicelevel":"","Cust_id":"0","Cust_branche":"","Cust_name":"","Cust_address1":"","Cust_zipcode":"","Cust_city":"","Cust_country":"","Cust_Phone":"","Cust_coachlevel":"","Site_Name":"E-set","Site_address1":"","Site_address2":"","Site_address3":"","Site_zipcode":"","Site_city":"","Site_country":"","Site_contact":"","Site_phone":"","activated":"1"},{"Firepack_sn":"20023901","Installation_Date":"","Type":"DH","Standard":"VAS","Capacity_m3h":"195","Pressure_bar":"4,2","Rpm":"2000","Power_kw":"72","Pump_Type":"KSB KFP50-200","Motor_Type":"DOOSAN PU066 VAS/CEA","Controller_Type":"WB882-E10 VAS","Pump_sn":"085259","Motor_sn":"EARPA209635","Controller_sn":"","Servicelevel":"","Cust_id":"0","Cust_branche":"","Cust_name":"","Cust_address1":"","Cust_zipcode":"","Cust_city":"","Cust_country":"","Cust_Phone":"","Cust_coachlevel":"","Site_Name":"D-set","Site_address1":"","Site_address2":"","Site_address3":"","Site_zipcode":"","Site_city":"","Site_country":"","Site_contact":"","Site_phone":"","activated":"0"}]');
$arr2 = json_decode('[{"user_id":"40009","firepack_id":"20012205","activated":"1"},{"user_id":"40009","firepack_id":"21020393","activated":"0"}]');
$firepackIds = array();
foreach($arr2 as $item){
$firepackIds[] = $item->firepack_id;
}
$goodRows = array();
foreach($arr1 as $item){
if(in_array($item->Firepack_sn, $firepackIds)){
$goodRows[] = $item;
}
}
echo json_encode($goodRows);
Hope this helps.
You do not need multiple loops or inefficient iterated in_array() calls. PHP already offers a native function to compare rows between multiple 2D arrays -- array_uintersect(). Because the custom callback uses rows from either array while making comparisons, you must build the callback's logic to fallback to potentially use either array's target column value.
Code: (Demo)
var_export(
array_uintersect(
$array1,
$array2,
fn($a, $b) =>
($a['Firepack_sn'] ?? $a['firepack_id'])
<=>
($b['Firepack_sn'] ?? $b['firepack_id'])
)
);
Output:
array (
0 =>
array (
'Firepack_sn' => '20012205',
'Installation_Date' => '',
'Type' => 'EH',
'Capacity_m3h' => '81',
'Pressure_bar' => '3,4',
'Rpm' => '2930',
'Power_kw' => '72',
),
)
I am trying to find the difference of 2 multidimensional arrays. I am attempting to solve this with a modified recursive array difference function.
If I have the following array setup:
$array1 = array(
0 => array(
'Age' => '1004',
'Name' => 'Jack'
),
1 => array (
'Age' => '1005',
'Name' => 'John'
)
);
$array2 = array(
0 => array(
'Age_In_Days' => '1004',
'Name' => 'Jack'
),
1=> array(
'Transaction_Reference' => '1005',
'Name' => 'Jack'
)
);
I am trying to match the arrays however the keys are not the same. I want to return the difference between the two multidimensional arrays where
$array1[$i]['Age'] == $array2[$i]['Age_In_Days'];
I want to keep the original array structure if the above condition holds true so the output I am looking for is:
$diff = array (1 => array (
'Age' => '1005',
'Name' => 'John'
));
However I am having issues with how to modify the recursive function to achieve this. Any help is appreciated! Thanks!
You need to loop through first array and compare values with second array. Then follows your condition. If condition is true then push this unique value to third array. Values in third array are now diff between first and second array.
$diff = [];
foreach ($array1 as $value1) {
foreach ($array2 as $value2) {
if ($value1['Age'] !== $value2['Age_In_Days']) {
array_push($diff, $value1);
}
}
}
I have a multi array e.g
$a = array(
'key' => array(
'sub_key' => 'val'
),
'dif_key' => array(
'key' => array(
'sub_key' => 'val'
)
)
);
The real array I have is quite large and the keys are all at different positions.
I've started to write a bunch of nested foreach and if/isset but it's not quite working and feels a bit 'wrong'. I'm fairly familiar with PHP but a bit stuck with this one.
Is there a built in function or a best practise way that I can access all values based on the key name regardless of where it is.
E.g get all values from 'sub_key' regardless of position in array.
EDIT: I see now the problem is that my "sub_key" is an array and therefore not included in the results as per the first comment here http://php.net/manual/en/function.array-walk-recursive.php
Just try with array_walk_recursive:
$output = [];
array_walk_recursive($input, function ($value, $key) use (&$output) {
if ($key === 'sub_key') {
$output[] = $value;
}
});
Output:
array (size=2)
0 => string 'val' (length=3)
1 => string 'val' (length=3)
You can do something like
$a = [
'key' => [
'sub_key' => 'val'
],
'dif_key' => [
'key' => [
'sub_key' => 'val'
]
]
];
$values = [];
array_walk_recursive($a, function($v, $k, $u) use (&$values){
if($k == "sub_key") {
$values[] = $v;
}
}, $values );
print_r($values);
How does it work?
array_walk_recursive() walks by every element of an array resursivly and you can apply user defined function. I created an anonymous function and pass an empty array via reference. In this anonymous function I check if element key is correct and if so it adds element to array. After function is applied to every element you will have values of each key that is equal to "sub_key"
I'm trying to add a key and value (associative) from an array to another array, where one specific key and value match. Here are the two arrays:
$array1 = array(
1 => array(
'walgreens' => 'location',
'apples' => 'product1',
'oranges' => 'product2'
),
2 => array(
'walmart' => 'location',
'apples' => 'product1',
'oranges' => 'product2',
'milk' => 'product3'
)
);
$array2 = array(
1 => array(
'walgreens' => 'location',
'apples' => 'product1',
'oranges' => 'product2',
'bananas' => 'product3',
)
);
Here is the attempt I made at modifying $array1 to have key 'bananas' and value 'product3':
$dataCJ = getCJItem($isbn);
foreach ($array1 as $subKey => $subArray) {
foreach($subArray as $dkey => $dval){
foreach($array2 as $cjk => $cjv){
foreach($cjv as $cjkey => $cjval){
if($dval['walgreens'] == $cjval['walgreens']){
$dval['bananas'] = $cjval['bananas'];
}
}
}
}
}
This doesn't work. How can I fix this?
Change => $dval to => &$dval. Currently you are creating and writing to a new variable and the update will not work in-place.
I would look at array_merge() function!
Here is a start with the PHP doc.
For your specific case, you could do the following :
foreach($array1 as $key1 => $values1){
foreach($array2 as $key2 => $values2){
if($values1[0] == $values2[0]){
$array1[$key1] = array_merge($values1, $values2);
}
}
}
Note to simplify the problem you should inverse the first key=> value pair of the array.
Having an array this way would be a lot simper :
array(
'location' => "The location (eg:walgreens)",
//...
);
This way you could change the comparison to the following instead :
$values1['location'] == $values2['location']
Which would be safer in the case the array is not built with the location as the first pair.