PHP Compare two multidimensional arrays - php

I have two multidimensional arrays like this:
Guest allow array
Array
(
[0] => 5
[1] => 2
[2] => 3
)
and second one like this
Array
(
[0] => Array
(
[property_id] => 6
[guest_allow] => 2
)
[1] => Array
(
[property_id] => 9
[guest_allow] => 3
)
[2] => Array
(
[property_id] => 62
[guest_allow] => 2
)
[3] => Array
(
[property_id] => 72
[guest_allow] => 3
)
[4] => Array
(
[property_id] => 76
[guest_allow] => 4
)
[5] => Array
(
[property_id] => 80
[guest_allow] => 5
)
[6] => Array
(
[property_id] => 84
[guest_allow] => 3
)
)
So I have to match guest array all values are present in second array as well as I have to check guest values is less than to second array of guest_allow. If there is not match single value return empty array. If match value so return only match value. I want return array like this:
Array
(
[0] => Array
(
[property_id] => 6
[guest_allow] => 2
)
[1] => Array
(
[property_id] => 9
[guest_allow] => 3
)
[2] => Array
(
[property_id] => 62
[guest_allow] => 2
)
[3] => Array
(
[property_id] => 72
[guest_allow] => 3
)
[4] => Array
(
[property_id] => 84
[guest_allow] => 3
)
[5] => Array
(
[property_id] => 76
[guest_allow] => 4
)
)
Is it possible return this type array? Thanks.

Assuming that $guestArr is your guest array and $secondArr is your second array, the solution would be like this:
foreach($secondArr as $key => $arr){
if(!in_array($arr['guest_allow'], $guestArr)){
unset($secondArr[$key]);
}
}
// display $secondArr array
var_dump($secondArr);
Here's the live demo.

$first = [1, 2, 3];
$second = [
['property_id' => 6, 'guest_allow' => 2],
['property_id' => 66, 'guest_allow' => 3],
['property_id' => 76, 'guest_allow' => 4],
['property_id' => 86, 'guest_allow' => 2]
];
$result = array_filter($second, function($el) use ($first) {
return in_array($el['guest_allow'], $first);
});

Related

Join Two arrays in php

I have two arrays and the First array name is $balances and output is below:
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
)
)
Second array name is $market and it's output:
Array
(
[0] => Array
(
[company] => SOUTHEASTB
[high] => 0
[low] => 0
)
[1] => Array
(
[company] => IFIC
[high] => 0
[low] => 0
)
[2] => Array
(
[company] => ABBANK
[high] => 0
[low] => 0
)
)
I merge this two array and getting bellow output. The 2nd array push the array value to 1st array using the code below producing a result which is not in my requirement:
$result = array();
foreach ($balances as $key => $value) {
$result[] = array_merge($value, $market[$key]);
}
Output:
Array
(
[0] => Array
(
[index] => 0
[company_code] => ABBANK
[company] => 1JANATAMF
[high] => 5.3
[low] => 5
)
[1] => Array
(
[index] => 6
[company_code] => IFIC
[company] => 1STPRIMFMF
[high] => 16.9
[low] => 16.2
)
[2] => Array
(
[index] => 11
[company_code] => SOUTHEASTB
[company] => AAMRANET
[high] => 44
[low] => 43
)
)
My challenge to check the $balances[company_code] == $market['company'] and append the 2nd array to 1st array which will produce the following result.
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[high] => 0
[low] => 0
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[high] => 0
[low] => 0
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[high] => 0
[low] => 0
)
)
But above code block is not serving my demand. Because this code block only push the second array to 1st array using merge function. I tried every other solution in my stock. Is there anyone who can give me any solution will be highly appreciated.
This can be solved in minimal code by using array_column to re-index both arrays by the company name, the two arrays can then be merged using array_merge_recursive:
$output = array_merge_recursive(array_column($balances, null, 'company_code'),
array_column($market, null, 'company'));
Output:
Array
(
[ABBANK] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[company] => ABBANK
[high] => 0
[low] => 0
)
[IFIC] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[company] => IFIC
[high] => 0
[low] => 0
)
[SOUTHEASTB] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[company] => SOUTHEASTB
[high] => 0
[low] => 0
)
)
If you want a numerically indexed result, just pass $output through array_values.
$output = array_values($output);
Demo on 3v4l.org
I have taken two arrays '$a' and '$b', in your case it is $balances and $market, respectively. array_push() is the simplest thing you can do to push/append values of array '$b' to array '$a'.
$a = array(array(
"index" => 0,
"account_id" => 1,
"company_id" => 6,
"company_code" => "ABBANK"
),
array
(
"index" => 6,
"account_id" => 1,
"company_id" => 147,
"company_code" => "IFIC"
),
array
(
"index" => 11,
"account_id" => 1,
"company_id" => 293,
"company_code" => "SOUTHEASTB"
));
$b = array
(
array
(
"company" => "SOUTHEASTB",
"high" => 0,
"low" => 0,
),
array
(
"company" => "IFIC",
"high" => 0,
"low" => 0,
),
array
(
"company" => "ABBANK",
"high" => 0,
"low" => 0
)
);
$result = array();
foreach($a as $key=>$value){
foreach($b as $key2 => $value2){
if($value['company_code'] === $value2['company']){
//append matched part of $b array to $a array value
array_push($value,$value2['high'],$value2['low']);
//append to result array
array_push($result, $value);
}
}
}
print_r($result);
//Output
Array
(
[0] => Array
(
[index] => 0
[account_id] => 1
[company_id] => 6
[company_code] => ABBANK
[0] => 0
[1] => 0
)
[1] => Array
(
[index] => 6
[account_id] => 1
[company_id] => 147
[company_code] => IFIC
[0] => 0
[1] => 0
)
[2] => Array
(
[index] => 11
[account_id] => 1
[company_id] => 293
[company_code] => SOUTHEASTB
[0] => 0
[1] => 0
)
)
While Nick's three-function approach is certainly attractive for its brevity, be aware that it stores the relating elements from both arrays (has redundant data in the output) and makes three iterating cycles.
A less concise alternative that doesn't require a recursive call is to forge a lookup array with one cycle (foreach()) and remove the unwanted element from the lookup, then iterate the balances array and swiftly merge related data set based on share company name values.
This assumes that the balances array should dictate which market values should be included in the result.
Code: (Demo)
$lookup = [];
foreach ($market as $row) {
$lookup[array_shift($row)] = $row;
}
var_export(
array_map(
fn($row) => $row + ($lookup[$row['company_code']] ?? []),
$balances
)
);

Sort a multidimensional an array with numeric keys but keep the keys same just change the order [duplicate]

This question already has an answer here:
PHP sort associative array by numeric key in asc order [duplicate]
(1 answer)
Closed 10 months ago.
So I have 3 dimensional array. I want that array to be reordered based on the keys but the value of the keys should remain as it is. Like for an example if the array keys are 5,2,4,1,3 then it should become 1,2,3,4,5. Below I'm providing the array I have and excepted array and the solutions I have tried.
This is the array I have :-
[5] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E3
[deal_text] =>
[units] => 5
[total_units] => 5
[amount] => 2620.8333333333
[is_freezed] =>
[can_sell] => 1
)
)
)
[2] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E4
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 516.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
[4] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => C8
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 526.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
[1] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => D4
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 557.14285714286
[is_freezed] => 1
[can_sell] =>
)
)
)
[3] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E5
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 516.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
Following are the solutions I have tried :-
$result = ksort($result);
$result = array_values($result);
$result = array_splice($result, 0, 0);
$result = sort($result);
$result = array_splice($result, 0, count($result));
This is the expected array :-
Array
(
[1] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => D4
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 557.14285714286
[is_freezed] => 1
[can_sell] =>
)
)
)
[2] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E4
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 516.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
[3] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E5
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 516.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
[4] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => C8
[deal_text] =>
[units] => 1
[total_units] => 0
[amount] => 526.66666666667
[is_freezed] => 1
[can_sell] =>
)
)
)
[5] => Array
(
[Anfield] => Array
(
[0] => Array
(
[slot] => E3
[deal_text] =>
[units] => 5
[total_units] => 5
[amount] => 2620.8333333333
[is_freezed] =>
[can_sell] => 1
)
)
)
)
Nothing is working any help will be appreciated. thanks in advance.
You are using ksort as $result = ksort($result);, ksort return TRUE/FALSE. That means you are assigning that to $results.
Read here PHP ksort
Your code should be:-
ksort($results);
instead of
$result = ksort($result);
You can use ksort for the keys sorting, here is an example
$arr = [
5 => [1,3],
3 => [2,3],
2 => [0,7]
];
ksort($arr);
echo '<pre>';
print_r($arr);
Output
Array
(
[2] => Array
(
[0] => 0
[1] => 7
)
[3] => Array
(
[0] => 2
[1] => 3
)
[5] => Array
(
[0] => 1
[1] => 3
)
)

Sort array based on different columns

I created an array based on a mysql table
Array (
[0] => Array ( [id] => 1 [parent_ID] => 0 )
[1] => Array ( [id] => 2 [parent_ID] => 0 )
[2] => Array ( [id] => 3 [parent_ID] => 2 )
[3] => Array ( [id] => 4 [parent_ID] => 2 )
[4] => Array ( [id] => 5 [parent_ID] => 2 )
[5] => Array ( [id] => 6 [parent_ID] => 1 )
[6] => Array ( [id] => 7 [parent_ID] => 1 )
[7] => Array ( [id] => 8 [parent_ID] => 1 )
[8] => Array ( [id] => 9 [parent_ID] => 1 )
I want to create a new array, where the order of the parent_ID is based on the ID. If the parent_ID from an array is “1”, than it needs to be placed directly after the array that has ID “1”. The output of the new array needs to be like this:
Array (
[0] => Array ( [id] => 1 [parent_ID] => 0 )
[1] => Array ( [id] => 6 [parent_ID] => 1 )
[2] => Array ( [id] => 7 [parent_ID] => 1 )
[3] => Array ( [id] => 8 [parent_ID] => 1 )
[4] => Array ( [id] => 9 [parent_ID] => 1 )
[5] => Array ( [id] => 2 [parent_ID] => 0 )
[6] => Array ( [id] => 3 [parent_ID] => 2 )
[7] => Array ( [id] => 4 [parent_ID] => 2 )
[8] => Array ( [id] => 5 [parent_ID] => 2 )
I tried to order my array by using the usort function, but that will only order the parent_ID or the ID column. Is it possible with PHP to sort an array like the example?
As said in my comment to the question your proposed result is bogus...
But here is some simple algorithm constructing such output:
<?php
$input = [
['id' => 1, 'parent_ID' => 0],
['id' => 2, 'parent_ID' => 0],
['id' => 3, 'parent_ID' => 2],
['id' => 4, 'parent_ID' => 2],
['id' => 5, 'parent_ID' => 2],
['id' => 6, 'parent_ID' => 1],
['id' => 7, 'parent_ID' => 1],
['id' => 8, 'parent_ID' => 1],
['id' => 9, 'parent_ID' => 1]
];
$data = [];
$output = [];
array_walk ($input, function($entry) use (&$data) {
$data[$entry['parent_ID']][] = $entry;
});
array_walk ($data[0], function($entry) use ($data, &$output) {
$output[] = $entry;
foreach ($data[$entry['id']] as $child) {
$output[] = $child;
}
});
print_r($output);
The output of executing that obviously is:
Array
(
[0] => Array
(
[id] => 1
[parent_ID] => 0
)
[1] => Array
(
[id] => 6
[parent_ID] => 1
)
[2] => Array
(
[id] => 7
[parent_ID] => 1
)
[3] => Array
(
[id] => 8
[parent_ID] => 1
)
[4] => Array
(
[id] => 9
[parent_ID] => 1
)
[5] => Array
(
[id] => 2
[parent_ID] => 0
)
[6] => Array
(
[id] => 3
[parent_ID] => 2
)
[7] => Array
(
[id] => 4
[parent_ID] => 2
)
[8] => Array
(
[id] => 5
[parent_ID] => 2
)
)
However I would like to make some comments to your situation:
you really should not store a value of 0 for the first elements. They do not have a parent, if I get your situation right, so that value should actually be null, not 0.
you should try to order your data right in the SQL query
you should rethink the overall approach since apparently you have huge issues sorting your data with the given data model. That typically is a sign of a modelling approach that should be reworked.

pop and push from one associative array to another array

I want to pop from array2 and want to push in array1.
But according to some custom requirement.
Now in array1 there is 1st key's readingOrder is 1 and 2nd key's readingOrder is 4.
So i want to push between this two key from array2's first two key.And same process for all other.
and my final array must be like array3.
for example in array1 key[0] readingOrder is 1 and key[1]'s 4. Now i want to push another two key from array2.
for array1 key[2] reading order is 6. so before this key i want to push another one key from array2 and same for further...
array1 is like below
Array
(
[0] => Array
(
[readingOrder] => 1
[id] => 78
)
[1] => Array
(
[readingOrder] => 4
[id] => 76
)
[2] => Array
(
[readingOrder] => 6
[id] => 80
)
)
array2 is like below
Array
(
[0] => Array
(
[id] => 81
[readingOrder] => 2
)
[1] => Array
(
[id] => 82
[readingOrder] => 5
)
[2] => Array
(
[id] => 84
[readingOrder] => 7
)
[3] => Array
(
[id] => 85
[readingOrder] => 8
)
[4] => Array
(
[id] => 86
[readingOrder] => 9
)
[5] => Array
(
[id] => 87
[readingOrder] => 10
)
[6] => Array
(
[id] => 88
[readingOrder] => 11
)
)
Output array3:
Array
(
[0] => Array
(
[readingOrder] => 1
[id] => 78
)
[1] => Array
(
[id] => 81
[readingOrder] => 2
)
[2] => Array
(
[id] => 82
[readingOrder] => 5
)
[3] => Array
(
[readingOrder] => 4
[id] => 76
)
[4] => Array
(
[id] => 84
[readingOrder] => 7
)
[5] => Array
(
[readingOrder] => 6
[id] => 80
)
[6] => Array
(
[id] => 85
[readingOrder] => 8
)
[7] => Array
(
[id] => 86
[readingOrder] => 9
)
[8] => Array
(
[id] => 87
[readingOrder] => 10
)
[9] => Array
(
[id] => 88
[readingOrder] => 11
)
)
Thanks..
You can build your array like that:
$current = 1;
$arr3 = [];
while ( $arr1 && $arr2 ) {
if ( $arr1[0]['readingOrder'] > $current )
$arr3[] = array_shift($arr2);
else
$arr3[] = array_shift($arr1);
$current++;
}
$arr3 = array_merge($arr3, $arr1, $arr2);
print_r($arr3);
Note that this code is destructive for $arr1 and $arr2. If you want to preserve them, copy them before and use the copies instead.
You can do this with usort. First you need to merge the arrays:
$a1 = [
[
'readingOrder' => 1,
'id' => 78
],
[
'readingOrder' => 4,
'id' => 76
],
[
'readingOrder' => 6,
'id' => 80
]
];
$a2 = [
[
'readingOrder' => 2,
'id' => 81
],
[
'readingOrder' => 5,
'id' => 82
],
[
'readingOrder' => 7,
'id' => 84
],
[
'readingOrder' => 8,
'id' => 85
]
];
$a3 = array_merge($a1, $a2);
Then you need to use usort:
usort($a3, function($a,$b) {
if ($a['readingOrder'] == $b['readingOrder']) return 0;
return $a['readingOrder'] < $b['readingOrder'] ? -1 : 1;
});
In PHP 7 you can now use the spaceship operator, which would make the code more clean. Like so:
usort($a3, function($a,$b) {
return $a[0] <=> $b[0];
});
This will then return:
(
[0] => Array
(
[readingOrder] => 1
[id] => 78
)
[1] => Array
(
[readingOrder] => 2
[id] => 81
)
[2] => Array
(
[readingOrder] => 4
[id] => 76
)
[3] => Array
(
[readingOrder] => 5
[id] => 82
)
[4] => Array
(
[readingOrder] => 6
[id] => 80
)
[5] => Array
(
[readingOrder] => 7
[id] => 84
)
[6] => Array
(
[readingOrder] => 8
[id] => 85
)
)

Get top 5 values from multidimensional array in PHP [duplicate]

This question already has answers here:
How to sort an array of arrays in php?
(3 answers)
php - usort or array_multisort?
(3 answers)
Get the first N elements of an array?
(5 answers)
PHP: Any function that return first/last N elements of an array
(2 answers)
Closed 2 years ago.
I have the following array:
Array (
[0] => Array (
[count] => 9
[user_id] => 2
)
[1] => Array (
[count] => 25
[user_id] => 1
)
[2] => Array (
[count] => 20
[user_id] => 3 )
[3] => Array (
[count] => 6
[user_id] => 56 )
[4] => Array (
[count] => 2
[user_id] => 37 )
[5] => Array (
[count] => 1
[user_id] => 0
))
This is just a sample. The actual array will contain many more sub arrays.
I need to be able to obtain the top five values from "count" and store them with their associated "user_id".
The final result needs to look something like this:
Array (
[0] => Array (
[count] => 25
[user_id] => 1
)
[1] => Array (
[count] => 20
[user_id] => 3
)
[2] => Array (
[count] => 9
[user_id] => 2
)
[3] => Array (
[count] => 6
[user_id] => 56
)
[4] => Array (
[count] => 2
[user_id] => 37
)
[5] => Array (
[count] => 1
[user_id] => 0
) )
If this can be done by simply re ordering the array, that is fine.
Thanks!
You're looking for usort and array_slice.
Example:
<?php
$array = array(
array(
'count' => 9,
'user_id' => 2
),
array(
'count' => 25,
'user_id' => 1
),
array(
'count' => 20,
'user_id' => 3
),
array(
'count' => 6,
'user_id' => 56
),
array(
'count' => 2,
'user_id' => 37
),
array(
'count' => 1,
'user_id' => 0
)
);
function usort_callback($a, $b)
{
if ( $a['count'] == $b['count'] )
return 0;
return ( $a['count'] > $b['count'] ) ? -1 : 1;
}
usort($array, 'usort_callback');
$top5 = array_slice($array, 0, 5);
print_r($top5);
Outputs:
Array
(
[0] => Array
(
[count] => 25
[user_id] => 1
)
[1] => Array
(
[count] => 20
[user_id] => 3
)
[2] => Array
(
[count] => 9
[user_id] => 2
)
[3] => Array
(
[count] => 6
[user_id] => 56
)
[4] => Array
(
[count] => 2
[user_id] => 37
)
)
usort($array, function ($a, $b) { return $b['count'] - $a['count']; });
$top5 = array_slice($array, 0, 5);

Categories