PHP array_merge not doing exactly what i need it to do - php

Ok so here is my first array:
(
[1] => Array
(
[27] => Array
(
[product_id] => 27
[type] => hardware
[step_number] => 1
)
[372] => Array
(
[product_id] => 372
[type] => hardware
[step_number] => 1
)
[92] => Array
(
[product_id] => 92
[type] => hardware
[step_number] => 1
)
)
[2] => Array
(
[335] => Array
(
[product_id] => 335
[type] => hardware
[step_number] => 2
)
[62] => Array
(
[product_id] => 62
[type] => hardware
[step_number] => 2
)
[356] => Array
(
[product_id] => 356
[type] => hardware
[step_number] => 2
)
)
and here is my second array
(
[1] => Array
(
[655] => Array
(
[product_id] => 655
[type] => optional
[step_number] => 1
)
[54] => Array
(
[product_id] => 54
[type] => optional
[step_number] => 1
)
[554] => Array
(
[product_id] => 554
[type] => optional
[step_number] => 1
)
)
[2] => Array
(
[33] => Array
(
[product_id] => 33
[type] => optional
[step_number] => 2
)
[612] => Array
(
[product_id] => 612
[type] => optional
[step_number] => 2
)
[5] => Array
(
[product_id] => 5
[type] => optional
[step_number] => 2
)
)
[3] => Array
(
[444] => Array
(
[product_id] => 444
[type] => optional
[step_number] => 3
)
[6] => Array
(
[product_id] => 6
[type] => optional
[step_number] => 3
)
[53] => Array
(
[product_id] => 53
[type] => optional
[step_number] => 3
)
)
Basically what i need is the second array appended to the end of the first array with the keys of the first array preserved the keys and changing the step_number to the new key so the final keys looks like
(
[1] => Array
(
[27] => Array
(
[step_number] => 1)
....
[2] => Array
(
[335] => Array
(
[step_number] => 2)
....
[3] => Array
(
[655] => Array
(
[step_number] => 3)
....
[4] => Array
(
[33] => Array
(
[step_number] => 4)
....
[5] => Array
(
[444] => Array
(
[step_number] => 5)
....
but when i do
$all = array_merge($first, $second);
the keys are
(
[0] => Array
[1] => Array
[2] => Array
[3] => Array
[4] => Array
Is that possible to do....

Try array_merge_recursive .. http://php.net/array_merge_recursive

This is also from the manual on array_splice if you're just looking to append your 2nd array onto the first (http://php.net/manual/en/function.array-push.php):
array_splice($first, count($first), 0, $second);

Iterating over the first set of keys, then using the Union array operator should do the trick.
//$first = array(...);
//$second = array(...);
foreach ($second as $key => $value)
{
if (!isset($first[$key]))
{
$first[$key] = array();
}
$first[$key] += $value;
}

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

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

Rearrange items in multidimensional array

I have a multidimensional array, I want to take the key 'data' from each array item and form another array, like first array 'data' element has 3 items, second has 1 item, 3rd and 4th are empty, and 5th has one item, I want to make a separate array like $temp_array['first_item_from_first_array,..., first_item_from_fifth_array, 'second_item_from_second_array,....,second_item_From_fifth_array]
input array is,
Array
(
[0] => Array
(
[meal_type] => bf
[label] => Breakfast
[calorie_limit] => 30
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 109
[label] => testfrom
[quantity] => 12
[unit] => g
)
[1] => Array
(
[id] => 118
[label] => test
[quantity] => 200
[unit] => oz
)
[2] => Array
(
[id] => 121
[label] => test
[quantity] => 10
[unit] => g
)
)
)
[1] => Array
(
[meal_type] => sn
[label] => Snacks
[calorie_limit] => 10
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 120
[label] => testfrom
[quantity] => 12
[unit] => g
)
)
)
[2] => Array
(
[meal_type] => lu
[label] => Lunch
[calorie_limit] => 20
[total_calorie] => 0
[data] => Array
(
)
)
[3] => Array
(
[meal_type] => su
[label] => Supper
[calorie_limit] => 30
[total_calorie] => 0
[data] => Array
(
)
)
[4] => Array
(
[meal_type] => dn
[label] => Dinner
[calorie_limit] => 20
[total_calorie] => 0
[data] => Array
(
[0] => Array
(
[id] => 119
[label] => test
[quantity] => 200
[unit] => oz
)
)
)
)
the output to be like this
Array
(
[0] => Array
(
[0] => Array
(
[id] => 109
[label] => testfrom
[quantity] => 12
[unit] => g
)
[1] => Array
(
[id] => 120
[label] => testfrom
[quantity] => 12
[unit] => g
)
[2] => Array
(
)
[3] => Array
(
)
[4] => Array
(
[id] => 119
[label] => test
[quantity] => 200
[unit] => oz
)
)
[1] => Array
(
[0] => Array
(
[id] => 118
[label] => test
[quantity] => 200
[unit] => oz
)
[1] => Array
(
)
[2] => Array
(
)
[3] => Array
(
)
[4] => Array
(
)
)
[2] => Array
(
[0] => Array
(
[id] => 121
[label] => test
[quantity] => 10
[unit] => g
)
[1] => Array
(
)
[2] => Array
(
)
[3] => Array
(
)
[4] => Array
(
)
)
)
You need to do it like below:-
$data_array= array_column($array,'data');
$count = 0;
foreach($data_array as $data){
$real_count = count($data);
if($real_count > $count){
$count = $real_count;
}
}
echo $count;
$final_array = [];
foreach($data_array as $data_arr){
for($i=0;$i< $count; $i++){
$final_array[$i][] = (count($data_arr[$i])>0)? $data_arr[$i]: array();
}
}
echo "<pre/>";print_r($final_array);
Output:-https://eval.in/925383
Reference:- PHP: array_column - Manual
You can use array_column() function
Example :-
<?php
$array = [
[
"meal_type" => "bf",
"data" => [
"name" => "test",
"email" => "test#ymail.com"
]
],
[
"meal_type" => "bf",
"data" => []
]
];
echo "<pre>";
print_r(array_column($array, "data"));
?>
You can do this using foreach and array_push.
$data_item_array = [];
foreach ($array as $item) {
$data = $item['data'];
foreach ($data as $t) {
array_push($data_item_array, $t);
}
}
print_r($data_item_array);
Output will be :
Array
(
[0] => Array
(
[id] => 109
[label] => testfrom
[quantity] => 12
[unit] => g
)
[1] => Array
(
[id] => 118
[label] => test
[quantity] => 200
[unit] => oz
)
[2] => Array
(
[id] => 121
[label] => test
[quantity] => 10
[unit] => g
)
[3] => Array
(
[id] => 120
[label] => testfrom
[quantity] => 12
[unit] => g
)
[4] => Array
(
[id] => 119
[label] => test
[quantity] => 200
[unit] => oz
)
)

How to remove duplicate data in an array?

I have the following array:
Array
(
[0] => Array
(
[Import] => Array
(
[product_id] => 1
[id] => 1
[category_id] => 1
[amount] => 50
[cost] => 8320
[paid] => 0
[comment] => transportation and others cost: 100
[created] => 2015-06-22 12:09:20
)
[0] => Array
(
[total_sell] => 6
)
)
[1] => Array
(
[Import] => Array
(
[product_id] => 2
[id] => 2
[category_id] => 2
[amount] => 15
[cost] => 3000
[paid] => 0
[comment] =>
[created] => 2015-06-22 12:10:36
)
[0] => Array
(
[total_sell] => 1
)
)
[2] => Array
(
[Import] => Array
(
[product_id] => 1
[id] => 3
[category_id] => 1
[amount] => 15
[cost] => 2000
[paid] => 0
[comment] =>
[created] => 2015-06-22 12:10:58
)
[0] => Array
(
[total_sell] => 6
)
)
[3] => Array
(
[Import] => Array
(
[product_id] => 1
[id] => 4
[category_id] => 1
[amount] => 50
[cost] => 8000
[paid] => 0
[comment] =>
[created] => 2015-06-23 01:10:10
)
[0] => Array
(
[total_sell] => 6
)
)
)
I want to remove duplicate entry of [Import][product_id]. So my expected result is :
Array
(
[0] => Array
(
[Import] => Array
(
[product_id] => 1
[id] => 1
[category_id] => 1
[amount] => 50
[cost] => 8320
[paid] => 0
[comment] => transportation and others cost: 100
[created] => 2015-06-22 12:09:20
)
[0] => Array
(
[total_sell] => 6
)
)
[1] => Array
(
[Import] => Array
(
[product_id] => 2
[id] => 2
[category_id] => 2
[amount] => 15
[cost] => 3000
[paid] => 0
[comment] =>
[created] => 2015-06-22 12:10:36
)
[0] => Array
(
[total_sell] => 1
)
)
)
Would you write a function to filter this type of array and produce expected result. I have been googling for 2 days but no luck.
This is a handy one liner that should do the trick:
$unique= array_map("unserialize", array_unique(array_map("serialize", $original)));
If the underlying arrays are not identical, that won't work, in which case I think you could do:
$unique = array_intersect_key($original ,
array_unique(
array_map(function($item) {
return $item['Import']['product_id'];
}, $original)
)
);
Tested: http://sandbox.onlinephpfunctions.com/code/8aee5cbd614e0ddd1a03dfaa7e98c72fbbe7d68d
Here is a quick stable sort and reduce which runs in linearithmic time. First-encountered product Id's are kept, and entries with duplicate product Id's are ignored.
// Stable sort
sort($in);
// Reduce
$out = array_reduce($in, function(&$acc, &$item){
if($item['Import']['product_id'] !== #$acc[sizeof($acc)-1]['Import']['product_id']) {
$acc[] = $item;
}
return $acc;
}, []);
Demo: http://ideone.com/BP0eUJ
Update: Here is an even better linear-time algorithm that does the same as above using a fast "hash table" lookup. Again, the first-encountered product Id is kept and subsequent ones of the same Id are ignored.
$out = [];
$hashTable = [];
foreach($in as $item) {
$pid = $item['Import']['product_id'];
if(!isset($hashTable[$pid])) {
$out[] = $item;
$hashTable[$pid] = true;
}
}
Demo: http://ideone.com/5RF0og

Sorting arrays numerically [duplicate]

This question already has answers here:
Sort an array of associative arrays by column value
(23 answers)
Closed 4 months ago.
I have a PHP array that I need to sort. I have included the example array below. I need to put the top 10 number of URLS plus their perspective counts in a different array. I know I could run into problem if there aren't 10 top matches ... if that happens then a random matching would be fine.
Any suggestions?
I have tried sort(myarray) but that just sorts the first object in the array I need it to sort the second.
Any ideas?
Array
(
[0] => Array
(
[name] => http://bit.ly/2oUTzf
[count] => 1
)
[1] => Array
(
[name] => http://tiny.cc/wyNbi
[count] => 1
)
[2] => Array
(
[name] => http://ow.ly/Almo
[count] => 1
)
[3] => Array
(
[name] => http://bit.ly/7bQ8sY
[count] => 1
)
[4] => Array
(
[name] => http://kissa.be/w4V-
[count] => 5
)
[5] => Array
(
[name] => http://ow.ly/xzwI
[count] => 1
)
[6] => Array
(
[name] => http://twa.lk/L6FZX
[count] => 1
)
[7] => Array
(
[name] => http://tinyurl.com/Alyssa10
[count] => 1
)
[8] => Array
(
[name] => http://www.hiderefer.com/0cz7kNgA.htm
[count] => 1
)
[9] => Array
(
[name] => http://tinyurl.com/Joanie515
[count] => 1
)
[10] => Array
(
[name] => http://ow.ly/uJvB
[count] => 1
)
[11] => Array
(
[name] => http://tinyurl.com/
[count] => 1
)
[12] => Array
(
[name] => http://www.hiderefer.com/wJBUhh3G.htm
[count] => 1
)
[13] => Array
(
[name] => http://short.to/xcxc
[count] => 1
)
[14] => Array
(
[name] => http://bit.ly/t79FA
[count] => 2
)
[15] => Array
(
[name] => http://tinyurl.com/yzy33yl
[count] => 1
)
[16] => Array
(
[name] => http://p.gs/zksz6
[count] => 1
)
[17] => Array
(
[name] => http://bit.ly/7E1cc8
[count] => 1
)
[18] => Array
(
[name] => http://bit.ly/6hbugu
[count] => 1
)
[19] => Array
(
[name] => http://tii.libsyn.com/index.php
[count] => 6
)
[20] => Array
(
[name] => http://tinyurl.com/nlzzwq
[count] => 1
)
[21] => Array
(
[name] => http://bit.ly/7gAdXi
[count] => 1
)
[22] => Array
(
[name] => http://localtweeps.com
[count] => 1
)
[23] => Array
(
[name] => http://localtweeps.com.
[count] => 3
)
[24] => Array
(
[name] => http://scribd.com/doc/22365778
[count] => 1
)
[25] => Array
(
[name] => http://quick-weight-loss-secrets.com/
[count] => 1
)
[26] => Array
(
[name] => http://tinyurl.com/ykd5qm5
[count] => 1
)
[27] => Array
(
[name] => http://bit.ly/5DQ6SO
[count] => 1
)
[28] => Array
(
[name] => http://bit.ly/4z6Kww
[count] => 1
)
[29] => Array
(
[name] => http://bit.ly/40sm9N
[count] => 1
)
[30] => Array
(
[name] => http://bit.ly/8mh7DO
[count] => 5
)
[31] => Array
(
[name] => http://tinyurl.com/krt5yf
[count] => 1
)
[32] => Array
(
[name] => http://bit.ly/7GsthV
[count] => 1
)
[33] => Array
(
[name] => http://bit.ly/1QJzvM
[count] => 1
)
[34] => Array
(
[name] => http://yfrog.com/1durkj
[count] => 1
)
[35] => Array
(
[name] => http://budurl.com/dxwc
[count] => 9
)
[36] => Array
(
[name] => http://digg.com/d1qiCr
[count] => 1
)
[37] => Array
(
[name] => http://bit.ly/eVSIo
[count] => 1
)
[38] => Array
(
[name] => http://yfrog.com/37badgj
[count] => 2
)
[39] => Array
(
[name] => http://tinyurl.com/qh8sos
[count] => 1
)
[40] => Array
(
[name] => http://tinyurl.com/mz7l8d
[count] => 3
)
[41] => Array
(
[name] => http://tinyurl.com/nratac
[count] => 1
)
[42] => Array
(
[name] => http://tinyurl.com/yk587jx
[count] => 1
)
[43] => Array
(
[name] => http://www.bethel.edu/alumni/homecoming/09/events/
[count] => 1
)
[44] => Array
(
[name] => http://www.waytofit.net
[count] => 1
)
[45] => Array
(
[name] => http://twitpic.com/rdcy8
[count] => 1
)
[46] => Array
(
[name] => http://retwt.me/1C1Vd
[count] => 14
)
[47] => Array
(
[name] => http://www.starbucks.com/card
[count] => 1
)
[48] => Array
(
[name] => http://tinyurl.com/yhkbfqe
[count] => 13
)
[49] => Array
(
[name] => http://bit.ly/playspy
[count] => 1
)
[50] => Array
(
[name] => http://bit.ly/57rHLO
[count] => 12
)
You need to write a custom sorting function - like this:
function MyCustomSort($a, $b)
{
if ($a->count == $b->count) {
return 0;
}
return ($a->count < $b->count) ? -1 : 1;
}
Then you pass that function into a sort - like this:
usort($myArray, "MyCustomSort");
You could also write a function to help you sort by website - like this:
function MyCustomSort($a, $b)
{
if ($a->name == $b->name) {
return 0;
}
return ($a->name < $b->name) ? -1 : 1;
}
You may use decorate-sort-undecorate pattern.
<?php
$arr = Array
(
[0] => Array
(
[name] => http://bit.ly/2oUTzf
[count] => 1
)
[1] => Array
(
[name] => http://tiny.cc/wyNbi
[count] => 1
)
[2] => Array
(
[name] => http://ow.ly/Almo
[count] => 1
)
[3] => Array
(
[name] => http://bit.ly/7bQ8sY
[count] => 1
)
...
);
// actual sorting below
$arr= array_map(create_function('$a', 'return array($a["count"], $a);'), $arr); // transform into array of arrays consisted of sort key and item
sort($arr); // sort array of arrays
$arr = array_map('end', $arr); // take only last element from each array
print_r($arr);
How does it work?
Instead of sorting array of your items you sort array of arrays whose last element is item and first is the key by which you want to sort. After sorting you keep only the item.
You can use just sort for sorting array of arrays because PHP compares two same length arrays by comparing its elements one by one.
Sorting by multiple fields
You may use more then one sort key, for example sort by count and if counts are identical take url into account. You can do this by decorating with multiple keys with order of importance like so:
$arr = array_map(create_function('$a', 'return array($a["count"], $a["name"], $a);'), $arr);
Why it's fast
This way might be faster that using usort because it calls your custom code only n-times for sorting array of length n. Comparisons during sort are done using built in comparator so should be fast. In usort method custom comparator is called multiple times (more than n times) during sort and it may slow down things.
function sortByCount($a, $b)
{
if ($a['count'] == $b['count']) {
return 0;
}
return ($a['count'] < $b['count']) ? -1 : 1;
}
usort($myarray, "sortByCount");

Categories