Populate 2D array from each value in an array of arrays - php

I have a 2D array and I want to generate a formatted array. Actually I want to genetate multiple rows at a time by restructuring the input array.
My 2D array:
$occupied_ids = [
[8457, 6584],
[9874, 4586],
];
Expected output:
array (
0 =>
array (
'occupied_id' => 8457,
'feed' => 2,
'status' => 1,
'status_date' => '2022-09-13',
),
1 =>
array (
'occupied_id' => 6584,
'feed' => 2,
'status' => 1,
'status_date' => '2022-09-13',
),
2 =>
array (
'occupied_id' => 9874,
'feed' => 2,
'status' => 1,
'status_date' => '2022-09-13',
),
3 =>
array (
'occupied_id' => 4586,
'feed' => 2,
'status' => 1,
'status_date' => '2022-09-13',
),
)
My working code:
foreach($occupied_ids as $ele){
$attributes = array_map(function($v){
$feed = isset($_GET['feed']) ? $_GET['feed'] : 2;
$status = 1;
return [
'occupied_id' => $v,
'feed' => $feed,
'status' => $status,
'status_date' => date('Y-m-d'),
];
}, $ele);
/*Call function to multi-insert*/
//multi_insert($attributes);
}
But I'm looking for something a way without the outer loop.

Not sure how much better it is but I took a stab at it. Off to lunch but I'll revisit in a bit to see what can be optimized:
$occupied_ids = call_user_func_array('array_merge', $occupied_ids);
$temp = [ 'feed' => isset($_GET['feed']) ? $_GET['feed'] : 2,
'status' => 1,
'status_date' => date('Y-m-d'),
];
$attributes = array_map(function($v) use($temp) {
$r = $temp;
$r['occupied_id'] = $v;
return $r;
},
$occupied_ids);

Use array_reduce to flatten the first level of the array
$occupied_ids = [
[8457, 6584],
[9874, 4586],
];
function format_elem($v)
{
$feed = isset($_GET['feed']) ? $_GET['feed'] : 2;
return [
'occupied_id' => $v,
'feed' => $feed,
'status' => 1,
'status_date' => date('Y-m-d'),
];
}
$ids=array_reduce($occupied_ids,'array_merge',[]);
$attributes =array_map(format_elem,$ids);

By pre-flattening your data (by spreading the rows inside of an array_merge() call), you can call array_map() instead of array_reduce() because now the input will have the same number of rows as the desired output.
Code: (Demo)
var_export(
array_map(
fn($v) => [
'occupied_id' => $v,
'feed' => $_GET['feed'] ?? 2,
'status' => 1,
'status_date' => date('Y-m-d'),
],
array_merge(...$occupied_ids)
)
);

Related

set php variable contains only selected array

I have these array but I wanted it to echo an array only for the "watch" category and wanted to store the selected array in a PHP variable, I have to try to search the web to find the solution but no success.
$arr = [
'status' => 1,
'msg' => [
'total_records' => 5,
'total_pages' => 1,
'page_number' => 1,
'per_page' => 100,
'return_count' => 5,
'page_result' => [
0 => array
(
'items' => 200052001,
'code' => 501,
'category' => 'watch',
'price' => 50,
'stock' => 1,
),
1 => array
(
'items' => 200052001,
'code' => 401,
'category' => 'shirt',
'price' =>3,
'stock' => 1,
),
2 => array
(
'items' => 200052001,
'code' => 172758801,
'category' => 'watch',
'price' => 200,
'stock' => 1,
),
],
],
'errcode' => 0,
];
This should do the trick.
$watch_array = array();
foreach($arr["msg"]["page_result"] AS $k => $item) {
if($item["category"] == "watch") {
$watch_array[] = $item;
}
}
You now have an array containing only the watch.
To display its content, use:
print_r($watch_array);
Demo Link.
Check this search function for your requirement. Its completely dynamic along with recursive nature.
function search($array, $key, $value)
{
$results = [];
if (is_array($array)) {
if (isset($array[$key]) && $array[$key] == $value) {
$results[] = $array;
}
foreach ($array as $subarray) {
$results = array_merge($results, search($subarray, $key, $value));
}
}
return $results;
}
$temp = search($arr, "category", "watch");
Source.

Sorting array in PHP based on another array indexes

I have two arrays
// array of objects
$records = array(
[0] => (object) [
'id' => 1, // (*)
....
],
[1] => (object) [
'id' => 2, // (*)
....
],
[2] => (object) [
'id' => 3, // (*)
....
],
);
// array 2
// the keys in this array refer to the object ids (*)
$sorted = array(
'2' => 7,
'3' => 4,
'1' => 2,
);
$new_records = array();
What I want to do is to sort the values of first array (i.e the objects) based on the order of the key index of the second array, so the end result in this case will become:
$new_records = array(
[0] => (object) [
'id' => 2,
....
],
[1] => (object) [
'id' => 3,
....
],
[2] => (object) [
'id' => 1,
....
],
);
$records = $new_records;
Try this
$new_records = array();
foreach( $sort as $id => $pos ) {
foreach( $records as $record ) {
if( $record[ 'id' ] == $id ) {
$new_records[] = $record;
break;
}
}
}
This make the job
$records = array(
0 => (object) [
'id' => 1, // (*)
],
1 => (object) [
'id' => 2, // (*)
],
2 => (object) [
'id' => 3, // (*)
],
);
// array 2
// the keys in this array refer to the object ids (*)
$sorted = array(
'2' => 7,
'3' => 4,
'1' => 2,
);
$keySorted = array_keys($sorted);
usort($records, function ($a, $b) use ($keySorted) {
$pos_a = array_search($a->id, $keySorted);
$pos_b = array_search($b->id, $keySorted);
return $pos_a - $pos_b;
});
var_dump($records);
Here, I have created sorting of array and add to your array of object using current() and key() is from php.
$i = 0;
while ($value = current($sorted)) {
$key = key($sorted); // get key from array 2
$records[i]->array('id' => $key); // set key to array of object
next($array);
$i++;
}
I hope this may help you.
Code: (Demo)
$records = [(object)['id' => 1], (object)['id' => 2], (object)['id' => 3]];
$sorted = ['2' => 7, '3' => 4, '1' => 2];
$tempArr = array();
foreach ($records as $value) {
$tempArr[$value->id] = $value;
}
$resultArr = array_values(array_replace($sorted, $tempArr));
var_export($resultArr);
Output:
array (
0 =>
stdClass::__set_state(array(
'id' => 2,
)),
1 =>
stdClass::__set_state(array(
'id' => 3,
)),
2 =>
stdClass::__set_state(array(
'id' => 1,
)),
)

PHP finding same record in array

I would like to detect same records and then change quantity of the one record and delete the others. For example, given the following array:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
],
(int) 2 => [
'size' => '37',
'code' => '5',
'qn' => (int) 1
]
],
i would like to print:
'Cart' => [
(int) 0 => [
'size' => '38',
'code' => '5',
'qn' => (int) 1
],
(int) 1 => [
'size' => '37',
'code' => '5',
'qn' => (int) 2
]
],
It looks to me that you're trying to sum quantities (qn) on duplicate sizes (size) and codes (code). One way to achieve this is by looping through the array containing the cart items and building out a new array. I suggest reading about PHP arrays and array_key_exists to learn more as they're used below:
<?php
$arr = [
['size' => '38', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 5, 'qn' => 1],
['size' => '37', 'code' => 4, 'qn' => 1],
];
$newArr = [];
foreach ($arr as $value) {
$key = $value['size'] . ':' . $value['code'];
if (array_key_exists($key, $newArr)) {
$newArr[$key]['qn'] += $value['qn'];
continue;
}
$newArr[$key] = $value;
}
// Resets keys
$newArr = array_values($newArr);
print_r($newArr);
I dont know it is enough for your problem, but try function array_unique
Iterate your array and use array_diff on each subarray.
If the returned array doesn't contain neither size nor code, add the two qn
The function array_unique() works for single dimension array. To find unique elements from multi-dimension array, we need to do a little modification.
Try this:
$array = array_map("serialize", $array);
$output = array_map("unserialize", array_unique($array));
If you want to follow another approach, use this as a reference: Create multidimensional array unique
Please go through following code.
$result = [
0=> ['size' => '38',
'code' => '5',
'qn' => 1
],
1=> ['size' => '37',
'code' => '5',
'qn' => 1
],
2=> ['size' => '37',
'code' => '5',
'qn' => 1
]
];
$finalArr = [];
foreach($result as $k => $v) {
$flag = 0;
foreach($finalArr as $kc => $vc){
if($v['size']==$vc['size'] && $v['code']==$vc['code']){
$flag = 1;
$finalArr[$kc]['qn'] = $finalArr[$kc]['qn'] + 1;
break;
}
}
if($flag==0){
$finalArr[] =
[
'size' => $v['size'],
'code' => $v['code'],
'qn' => 1
];
}
}
echo "<pre>";
print_r($finalArr);
The code is tested against your question and i have explained the code. This gives you solution for any number of arrays and with similar array elements with quantity(qn) incremented as you wanted:
<?php
//Compare the 1st and 2nd array
//Compare the 2st and 3rd array
// and so on
function compare($arr1 = array(), $arr2 = array()) {
$result = array_diff($arr1, $arr2);
return $result;
}
$cart = array(
0 => array('size' => 38, 'code' => 5, 'qn' => 1),
1 => array('size' => 37, 'code' => 5, 'qn' => 1),
2 => array('size' => 37, 'code' => 5, 'qn' => 1),
);
$j = 1;
$cart_total_count = count($cart);//Gives the count of your cart
$final_cart = array();//Final array with qn incremented
for($i=0;$i<$cart_total_count; $i++) {
if (!empty($cart[$i+1])) {//If 2nd array is not present then stop the comparision
if (empty(compare($cart[$i], $cart[$i+1]))){
$j++;
$cart[$i]['qn'] = $j;
$final_cart = $cart[$i];
}
}
}var_dump($final_cart);
//Output
//1. If 2 array are same
//array(3) { ["size"]=> int(37) ["code"]=> int(5) ["qn"]=> int(2) }
//2. If no array are same
//array(0) { }?>

return inside foreach php and laravel

I trying to return data every time inside the foreach() but i keep on getting the data on the first iteration of the loop here is my code
for ($i = 0 ;$i<4;$i++)
{
var_dump($i);
$publisher = Publisher::find($results[$i]->publisherId);
//pr($publisher);
$channels =$publisher->channels()->get() ;
pr($channels[0]);
$data = ReviveAgent::getPublisherDailyStatistics($channels[0],$start,$end);
pr($data);
return Response::json($data);
}
on the var_dump($i);
It only shows data for the first 0 only.So how can i return the data also for 1,2,3
here is my output when pr($data) for var_dump($i) = 1
array (
0 =>
array (
'impressions' => 1867,
'clicks' => 14,
'requests' => 44,
'revenue' => 2.79,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150518T00:00:00',
'timestamp' => 1431907200,
'xmlrpc_type' => 'datetime',
)),
),
1 =>
array (
'impressions' => 2197,
'clicks' => 17,
'requests' => 382,
'revenue' => 19.829999999999998,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150519T00:00:00',
'timestamp' => 1431993600,
'xmlrpc_type' => 'datetime',
)),
),
2 =>
array (
'impressions' => 5484,
'clicks' => 3,
'requests' => 3680,
'revenue' => 6.7300000000000004,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150520T00:00:00',
'timestamp' => 1432080000,
'xmlrpc_type' => 'datetime',
)),
),
3 =>
array (
'impressions' => 6909,
'clicks' => 105,
'requests' => 5141,
'revenue' => 378.88499999999999,
'day' =>
stdClass::__set_state(array(
'scalar' => '20150521T00:00:00',
'timestamp' => 1432166400,
'xmlrpc_type' => 'datetime',
)),
),
The return operator implicitly ends the current execution scope. The context of your usage is not given, but you could put your $data into an array prior to JSON encoding and returning it. It might look something like this:
$data = array();
for ($i = 0; $i < 4; $i++) {
...
$record = ReviveAgent::getPublisherDailyStatistics($channels[0], $start, $end));
pr($record);
$data[] = $record;
}
return Response::json($data);
You can take this example in laravel
Here I am returning multiple Prices
$prices = $this->Prices;
foreach ($prices as $price) {
$res[] = [
'travel_mode_id' =>$price->travel_mode_id,
'occupancy_id' => $price->occupancy_id,
'rider_id' => $price->occupancy_id,
'price' => $price->price,
];
}
return $res;

PHP Merge by values in same array

So I have this array in PHP.
$arr = [
[ 'sections' => [1], 'id' => 1 ],
[ 'sections' => [2], 'id' => 1 ],
[ 'sections' => [3], 'id' => NULL ],
[ 'sections' => [4], 'id' => 4 ],
[ 'sections' => [5], 'id' => 4 ],
[ 'sections' => [6], 'id' => 4 ]
];
I want to merge on 'id' and get something like
$arr = [
[ 'sections' => [1, 2], 'id' => 1 ],
[ 'sections' => [3], 'id' => NULL ],
[ 'sections' => [4, 5, 6], 'id' => 4 ]
];
Just struggling to get my head around this one. Any Ideas
I've created this quick function that might work for you
<?php
// Your array
$arr = array(
array( 'elem1' => 1, 'elem2' => 1 ),
array( 'elem1' => 2, 'elem2' => 1 ),
array( 'elem1' => 3, 'elem2' => NULL ),
array( 'elem1' => 4, 'elem2' => 4 ),
array( 'elem1' => 5, 'elem2' => 4 ),
array( 'elem1' => 6, 'elem2' => 4 )
);
print_r($arr);
function mergeBy($arr, $elem2 = 'elem2') {
$result = array();
foreach ($arr as $item) {
if (empty($result[$item[$elem2]])) {
// for new items (elem2), just add it in with index of elem2's value to start
$result[$item[$elem2]] = $item;
} else {
// for non-new items (elem2) merge any other values (elem1)
foreach ($item as $key => $val) {
if ($key != $elem2) {
// cast elem1's as arrays, just incase you were lazy like me in the declaration of the array
$result[$item[$elem2]][$key] = $result[$item[$elem2]][$key] = array_merge((array)$result[$item[$elem2]][$key],(array)$val);
}
}
}
}
// strip out the keys so that you dont have the elem2's values all over the place
return array_values($result);
}
print_r(mergeBy($arr));
?>
Hopefully it'll work for more than 2 elements, and you can choose what to sort on also....

Categories