pop and push from one associative array to another array - php

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
)
)

Related

PHP Subtract multidimensional arrays based on 2 values

I need to subtract the qt from two arrays based on id and type, keeping the array complete.
How do I do in php to be able to subtract these arrays?
I have 2 arrays:
=> this is the first array with multiple key "down"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => down
[qt] => 12
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => down
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => down
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => down
[qt] => 45
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => down
[qt] => 3
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
=> this is the second array with multiple key "up"
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => up
[qt] => 5
)
[1] => Array
(
[id] => 86
[loc] => 3
[type] => up
[qt] => 27
)
[2] => Array
(
[id] => 23
[loc] => 9
[type] => up
[qt] => 3
)
)
=> I need cubtract "qt" (if "id" and "loc" are the same then subtract the "qt")
Array
(
[0] => Array
(
[id] => 26
[loc] => 1
[type] => total
[qt] => 7
)
[1] => Array
(
[id] => 32
[loc] => 1
[type] => total
[qt] => 34
)
[2] => Array
(
[id] => 26
[loc] => 2
[type] => total
[qt] => 5
)
[3] => Array
(
[id] => 86
[loc] => 3
[type] => total
[qt] => 18
)
[4] => Array
(
[id] => 23
[loc] => 9
[type] => total
[qt] => 0
)
[5] => Array
(
[id] => 23
[loc] => 3
[type] => down
[qt] => 99
)
)
Try this out
function findMatch($array, $id, $loc)
{
foreach ($array as $key => $item) {
if ($item["id"] == $id and $item["loc"] == $loc) {
return $key;
}
}
return false;
}
$total = [];
foreach($down as $d) {
$matched = findMatch($up, $d["id"], $d["loc"]);
if($matched !== false){
$total[] = array_replace($d, [
"type" => "total",
"qt" => ($d["qt"] - $up[$matched]["qt"])
]);
} else {
$total[] = array_replace($d, ["type" => "total"]);
}
}
print_r($total);

Find array which has duplicate array

I have array like below, you can see 71 and 33 are duplicate value so I need find those array which has duplicate values
Array
(
[0] => Array
(
[0] => 71
[1] => 33
[2] => 46
)
[1] => Array
(
[0] => 71
)
[4] => Array
(
[0] => 71
[1] => 33
)
)
Expected output: I want array something like below
Array
(
[71] => Array
(
[0] => 0
[1] => 1
[2] => 4
)
[33] => Array
(
[0] => 0
[1] => 4
)
)
You could loop over the main array and values to store index a new array. Finally, you could reduce it to keep only duplicates using array_filter():
$array = array(
0 => array(
0 => 71,
1 => 33,
2 => 46
),
1 => array(
0 => 71
),
4 => array(
0 => 71,
1 => 33
)
);
// loop over the main array:
foreach ($array as $index => $arr_values) {
// loop over values:
foreach ($arr_values as $value) {
$out[$value][] = $index;
}
}
// finally, remove entries with only one values:
$out = array_filter($out, function($values) { return count($values) > 1 ; });
print_r($out);
Outputs:
Array
(
[71] => Array
(
[0] => 0
[1] => 1
[2] => 4
)
[33] => Array
(
[0] => 0
[1] => 4
)
)

PHP Compare two multidimensional arrays

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);
});

PHP - UNSET Elements in a Deep Mixed Index/Associative Array

I have a mixed index/associative array in PHP that can, in theory, be infinitely deep because some elements may have 'children' arrays. I attach a slimmed down example. The php array is derived from some JSON data.
I want to search on a given key/value pair and to delete any elements matching that pair at the index level.
So for example, in the array below, I wish to search for the key of 'formId' and a value of '44' and to delete elements such that $array[0][0][0][0] and $array[0][1] are removed. Obviously I will then need to re-number the array.
I need to be able to search on any key/value pair... only one pair at a time is necessary... that is to say that the above example of 'formId' of '44' might be 'viewId' of '16' next time.
I have tried numerous ways to do this, with iterators, recursive foreach loops, &$reference keys but I just cannot seem to get it right.
Array
(
[0] => Array
(
[formId] => 0
[subId] => 0
[viewId] => 0
[id] => 0
[children] => Array
(
[0] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 16
[id] => _st_node_5328_0_0
[children] => Array
(
[0] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 16
[id] => _st_node_3838_0_0_0
[children] => Array
(
[0] => Array
(
[formId] => 44
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_0
)
[1] => Array
(
[formId] => 7
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_1
)
[2] => Array
(
[formId] => 3
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_2
)
[3] => Array
(
[formId] => 10
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_3
)
[4] => Array
(
[formId] => 9
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_4
)
[5] => Array
(
[formId] => 8
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_5
)
[6] => Array
(
[formId] => 6
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_6
)
[7] => Array
(
[formId] => 5
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_7
)
[8] => Array
(
[relId] => 167
[formId] => 4
[text] => Laptop Computers
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_8
[isActive] =>
)
[9] => Array
(
[formId] => 1
[subId] =>
[viewId] => 16
[id] => _st_node_947_0_0_0_9
)
)
)
[1] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 1
[id] => _st_node_3838_0_0_1
)
[2] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 11
[id] => _st_node_3838_0_0_2
)
[3] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 12
[id] => _st_node_3838_0_0_3
)
[4] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 13
[id] => _st_node_3838_0_0_4
)
[5] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 14
[id] => _st_node_3838_0_0_5
)
[6] => Array
(
[formId] => 1
[subId] => 0
[viewId] => 110
[id] => _st_node_3838_0_0_6
)
)
)
[1] => Array
(
[formId] => 44
[subId] => 0
[viewId] => 144
[id] => _st_node_5328_0_1
)
[2] => Array
(
[formId] => 10
[subId] => 0
[viewId] => 26
[id] => _st_node_5328_0_2
)
[3] => Array
(
[formId] => 9
[subId] => 0
[viewId] => 9
[id] => _st_node_5328_0_3
)
[4] => Array
(
[formId] => 8
[subId] => 0
[viewId] => 8
[id] => _st_node_5328_0_4
)
[5] => Array
(
[formId] => 7
[subId] => 0
[viewId] => 25
[id] => _st_node_5328_0_5
)
[6] => Array
(
[formId] => 6
[subId] => 0
[viewId] => 6
[id] => _st_node_5328_0_6
)
[7] => Array
(
[formId] => 5
[subId] => 0
[viewId] => 5
[id] => _st_node_5328_0_7
)
[8] => Array
(
[formId] => 4
[subId] => 0
[viewId] => 4
[id] => _st_node_5328_0_8
)
[9] => Array
(
[formId] => 3
[subId] => 0
[viewId] => 3
[id] => _st_node_5328_0_9
)
)
)
)
The idea
Since you want to unset elements, you definitely want to pass the $array into the function as a reference (&$array).
You want to use recursion to allow you to dig as deep as necessary based on the actual array.
You loop over all elements of the array and the first thing you do is check whether an element is an array. If it is, you check if that subarray matches your criteria. If it does, you remove it. If it doesn't you invoke the function with the same $key, $value pair on that subarray.
The code
function removeMatching($key, $value, &$arr) {
// Iterate over all $arr elements
foreach ($arr as $i => $subarr) {
// Skip all elements that are not arrays
if (is_array($subarr)) {
// Check if the sub-array matches the criteria
if (isset($subarr[$key]) && $subarr[$key] === $value) {
// Remove it from the main array if it does
unset($arr[$i]);
} else {
// If the sub-array didn't match the criteria
// Check if it contains any other matching sub-arrays
removeMatching($key, $value, $arr[$i]);
}
}
}
}
Apply like this:
$array = []; // your array
removeMatching('formId', 44, $array);
var_dump($array);

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