array_reduce to use dynamic variables pass in second function - php

I have below $test array
Array
(
[0] => Array
(
[quantity] => 3
[stock_id] => _PHONE
)
[1] => Array
(
[quantity] => 3
[stock_id] => 102
)
[2] => Array
(
[quantity] => 4
[stock_id] => _PHONE
)
[3] => Array
(
[quantity] => 3
[stock_id] => 102
)
[4] => Array
(
[quantity] => 4
[stock_id] => _PHONE
)
[5] => Array
(
[quantity] => 6
[stock_id] => _PHONE
)
[6] => Array
(
[quantity] => 2
[stock_id] => 102
)
)
and to sum same stock_id keys to one, i use below functions:
function sum($array, $key){
isset($array[$key['stock_id']]) ? $array[$key['stock_id']]['quantity'] += $key['quantity'] : $array[$key['stock_id']] = $key;
return $array;
};
//merge same stock_id and sum the quantity same stock id
$sum_same_stock_id = array_reduce($test, "sum");
and the result went well like below:
$sum_same_stock_id:
Array
(
[_PHONE] => Array
(
[quantity] => 17
[stock_id] => _PHONE
)
[102] => Array
(
[quantity] => 8
[stock_id] => 102
)
)
So the question here is, I wanted to pass an dynamic keys values not just fixed values stock_id & quantity in sum function above. Have tried variety ways but still can't figured out the way. And can we put those functions into class as well?
Any advise is appreciated!

Maybe you can use the "use" function for the callback?
See https://www.php.net/manual/en/functions.anonymous.php

Related

PHP reduce and merge? an array in several steps

I'm trying to reduce/merge an array looking like this
$test = Array
(
[0] => Array
(
[id] => 150023
[rowtext] => part 1
[rowpartnumber] => 4360
[qty] => 2.00
[min_delper] => 2021-07-28
)
[1] => Array
(
[id] => 150026
[rowtext] => part 2
[rowpartnumber] => 4360
[qty] => 2.00
[min_delper] => 2021-07-29
)
[2] => Array
(
[id] => 150023
[rowtext] => part 3
[rowpartnumber] => 4361
[qty] => 4.00
[min_delper] => 2021-08-22
)
[3] => Array
(
[id] => 150023
[rowtext] => part 4
[rowpartnumber] => 4362
[qty] => 2.00
[min_delper] => 2021-09-22
)
);
I want to sum the [qty] where [rowpartnumber] are the same, I can achieve this with
$summa_test = array_reduce($test, function ($a, $b) {
isset($a[$b['rowpartnumber']]) ? $a[$b['rowpartnumber']]['qty'] += $b['qty'] : $a[$b['rowpartnumber']] = $b;
return $a;
});
But I would also like to take the [id] where [rowpartnumer] are the same and add it to [id]
so the output should look like this:
Array
(
[0] => Array
(
[id] => 150023 150026
[rowtext] => part 1
[rowpartnumber] => 4360
[qty] => 4.00
[min_delper] => 2021-07-28
)
[1] => Array
(
[id] => 150023
[rowtext] => part 3
[rowpartnumber] => 4361
[qty] => 4.00
[min_delper] => 2021-08-22
)
[2] => Array
(
[id] => 150023
[rowtext] => part 4
[rowpartnumber] => 4362
[qty] => 2.00
[min_delper] => 2021-09-22
)
);
Can't seem to get my head around it, so a little help from you experts would be great, thank you
You have to modify the callback function to concatenate the id to the previous one if the rowpartnumber already exits. Like this:
$summa_test = array_reduce($test, function ($carry, $item) {
if (isset($carry[$item['rowpartnumber']])) {
$carry[$item['rowpartnumber']]['qty'] += $item['qty'];
$carry[$item['rowpartnumber']]['id'] .= " ".$item['id'];
}
else {
$carry[$item['rowpartnumber']] = $item;
}
return $carry;
});
I don't know whether it is a problem, but because of the concatenation id will become a string where multiple ids are found - but remains integer when only one. If it is a problem for you, there are two options:
Convert to string even if only one id
Use an array to store to multiple ids.
(I changed the parameter names to the ones used in PHP documentation - you can change it back, but generally it is a good idea to keep that way - others will more easily understand your code.)

search and unset array in array by value in php

My array look like this :
[cart_seller] => Array
(
[3] => Array
(
[หมวด1เลือก1 หมวด2เลือก1 1705] => Array
(
)
)
[4] => Array
(
[# 801] => Array
(
)
)
)
[cart_product] => Array
(
[หมวด1เลือก1 หมวด2เลือก1 1705] => Array
(
[id] => 1705
[name] => ทดสอบสินค้า
[image] => p1534937865-VASAVAT LAB N MEDIA LOGO W.png
[price] => 1111
[option] => หมวด1เลือก1 หมวด2เลือก1
[amount] => 1
)
[# 801] => Array
(
[id] => 801
[name] => โบว์แพรแถบ ร.9 ชนมพรรษา 84 พรรษา ปีพุทธศักราช 2554
[image] => p1498062217-ส.jpg
[price] => 90
[option] =>
[amount] => 1
)
)
I want unset '# 801' in cart_seller and cart_product
in cart_product use unset($cart['cart_product'][# 801]);
but in cart_seller it in array [4] what can i do without reference value (4) ?
exapmle unset($cart['cart_seller'][xxxx][# 801]);
Just loop cart seller array til you find #801.
foreach($cart['cart_seller'] as $key => $c){
if(array_key_exists("#801",$c)){
unset($cart['cart_seller'][$key]['#801']);
}
}

PHP match values between 2 arrays not same key

I have made researches and havent fount any solutions for this yet. So final thought is come to Stackoverflow and ask the question.
I have 2 array like below:
BigArray
Array
(
[0] => Array
(
[id] => 1
[category_name] => Accountancy
[category_name_vi] => Kế toán
[category_id] => 1
)
[1] => Array
(
[id] => 2
[category_name] => Armed forces
[category_name_vi] => Quân đội
[category_id] => 2
)
[2] => Array
(
[id] => 3
[category_name] => Admin & Secretarial
[category_name_vi] => Thư ký & Hành chính
[category_id] => 3
)
[3] => Array
(
[id] => 4
[category_name] => Banking & Finance
[category_name_vi] => Tài chính & Ngân hàng
[category_id] => 4
)
)
and SmallArray:
Array
(
[0] => Array
(
[id] => 7
[category_id] => 2
[jobseeker_id] => 1
)
[1] => Array
(
[id] => 8
[category_id] => 3
[jobseeker_id] => 1
)
)
Ok, now I wanted to match each category_id from SmallArray link with respectively category_name from BigArrayand the output I only need matched values between SmallArray and BigArraywhere category_id of SmallArray is key and category_name of BigArray is value like below:
Matched array:
Array
(
[0] => Array
(
[2] => Armed forces
)
[1] => Array
(
[3] => Admin & Secretarial
)
)
So far, I have tried array_intersect, 2 foreach loops but no luck. Any advise would be very appreciated :(
Thanks
This should do that:
foreach ($smallArray as $smallKey => $smallElement) {
foreach ($bigArray as $bigKey => $bigElement) {
if ($bigElement['id'] == $smallElement['category_id']) {
$smallArray[$smallKey] = array(
$bigElement['id'] => $bigElement['category_name'],
);
break; // for performance and no extra looping
}
}
}
After these loops, you have what you want in $smallArray.

How insert array value in each index of another array in php?

I am having two arrays, in that i need to insert the each index of last key and value of another array keys, values in php. My sample arrays are given below. I am using codeigniter framework.
First array:
Array
(
[0] => stdClass Object
(
[customer_name] => Cash
[ordernumber] => 6452424
[product_name] => Bacardi Rum
[quantity] => 1
[unit_price] => 25.00
[inv_discount] => 0.00
[salesman_id] => 25,27
)
[1] => stdClass Object
(
[customer_name] => Cash
[ordernumber] => 6452424
[product_name] => Baileys
[quantity] => 1
[unit_price] => 15.00
[inv_discount] => 0.00
[salesman_id] => 28,29
)
)
Second array:
Array
(
[0] => 140140,150150
[1] => 151151,05180518
)
And i need the o/p :
Array
(
[0] => stdClass Object
(
[customer_name] => Cash
[ordernumber] => 6452424
[product_name] => Bacardi Rum
[quantity] => 1
[unit_price] => 25.00
[inv_discount] => 0.00
[salesman_id] => 25,27
[salesman] => 140140,150150
)
[1] => stdClass Object
(
[customer_name] => Cash
[ordernumber] => 6452424
[product_name] => Baileys
[quantity] => 1
[unit_price] => 15.00
[inv_discount] => 0.00
[salesman_id] => 28,29
[salesman] => 151151,05180518
)
)
Can any one help me, give some ideas to solve this.
In this case, you have an array of objects (stdClass type) and one other array only. Answering your question you just have to do the code as shown below.
foreach ($secondArray as $key => $value) {
$firstArray[$key]->salesman = $value;
}
or
foreach ($firstArray as $key => $object) {
$object->salesman = $firstArray[$key];
}
foreach($arrA as $key=>$val){
$arrA[$key]['salesman'] = $arrB[$key];
}
As long as both arrays will be same size, array_map will be suitable:
$resultArray = array_map(function ($rowA, $rowB) {
$rowA->salesman = $rowB;
return $rowA;
}, $firstArray, $secondArray);

How to loop through subarray to see if value is return in string

Here is an example of an array that is output:
Array ( [CART] => Array ( [ITEMS] => Array ( [0] => Array ( [product_id] => 269194 [variation_id] => 0 [options] => Array ( ) [quantity] => 1 [product_name] => 15 Top Hits for Easy Piano [product_code] => HL102668 [product_price] => 14.9900 [original_price] => 14.9900 [default_currency] => 1 [customer_group] => [product_fields] => Array ( ) ) [1] => Array ( [product_id] => 266421 [variation_id] => 0 [options] => Array ( ) [quantity] => 1 [product_name] => Whistle [product_code] => HD245839 [product_price] => 3.9900 [original_price] => 3.9900 [default_currency] => 1 [customer_group] => [product_fields] => Array ( ) ) ) [LAST_UPDATED] => 1349829499 [NUM_ITEMS] => 2 ) [JustAddedProduct] => [CHECKOUT] => Array ( ) )
There is an array for each unique product (in this example there are 2 unique products.) Sometimes there will be just one, sometimes there could be 20 or more unique products.
The value that is important to me is [product_code]. You can see that in the first array, there is [product_code] => HL102668. In the second there is [product_code] => HD245839.
How can I check to see if 'HD' exists in any of the [product_code] values? If it does, I need to return false.
Thank you for your help!
Access your sub array :
$products = $array['CART']['ITEMS'];
Loop through your sub array :
foreach ($products as $product)
Check if HD exists in your product_code, with either simple strstr, or with regex using preg_match (if you are comfortable with it).
if (strstr($product['product_code'], "HD")) {
// Do your actions
}

Categories