return inside foreach php and laravel - php

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;

Related

I have a array like this in laravel , I want to remove the array which is having total greater than 480 [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 months ago.
Improve this question
array (
0 =>
array (
'user_code' => '073',
'name' => 'Ashish',
'email' => 'ashishm#gmail.com',
),
1 =>
array (
'user_code' => '073',
'date' => '2022-07-04',
'total' => '915',
),
2 =>
array (
'user_code' => '073',
'date' => '2022-07-05',
'total' => 0,
),
3 =>
array (
'user_code' => '073',
'date' => '2022-07-06',
'total' => '360',
),
)
If I understand you correctly, you have an array that contains 4 entries. Each of those are arrays. You want to remove the one that has total = 915. This would be the resulting array:
array (
0 =>
array (
'user_code' => '073',
'name' => 'Ashish',
'email' => 'ashishm#gmail.com',
),
1 =>
array (
'user_code' => '073',
'date' => '2022-07-05',
'total' => 0,
),
2 =>
array (
'user_code' => '073',
'date' => '2022-07-06',
'total' => '360',
),
)
Is this what you are looking for or are you trying to remove several entries whenever the total exceeds 480 via some sort of script or validation before it's created. If so, I need to see more code to understand where this array comes from.
----EDITED AFTER FURTHER INFO PROVIDED ------
So it sounds like you are getting two arrays from a database and then merging them. Is this what you are doing?
$arrayOne = array(
0 =>
array(
'user_code' => '073',
'name' => 'Ashish',
'email' => 'ashishm#gmail.com',
),
1 =>
array(
'user_code' => '078',
'name' => 'Tyler',
'email' => 'test#example.com',
),
);
$arrayTwo = array(
0 =>
array(
'user_code' => '073',
'date' => '2022-07-04',
'total' => '915',
),
1 =>
array(
'user_code' => '073',
'date' => '2022-07-05',
'total' => 0,
),
2 =>
array(
'user_code' => '073',
'date' => '2022-07-06',
'total' => '360',
),
4 =>
array(
'user_code' => '073',
'date' => '2022-07-04',
'total' => '805',
),
5 =>
array(
'user_code' => '073',
'date' => '2022-07-04',
'total' => '10000',
),
);
$mergedArray = array_merge($arrayOne, $arrayTwo);
If so, array_filter should work. #Bruce solution was close but it was not testing the value below 480.
$filteredArray = array_filter($mergedArray, function ($val) {
if (!isset($val['total'])) return true;
if ($val['total'] < 480) return true;
return false;
});
Can you try this :
array_filter ($test, function ($val) {
return !isset($val['total']) || $val['total'] < 480;
})
Where $test contains your Array. I added the !isset($val['total']) because the first array does not have the 'total' key and I don't know if you want to keep it or not.
Use this class to filter an array:
use Illuminate\Support\Arr;
In your controller function:
$filteredArray = Arr::where($myArray, function ($value, $key) {
$total = 0;
if (is_array($value) && array_key_exists('total', $value)) {
$total = intval($value['total']);
}
return ($total <= 480);
});
If the value of $total you need to filter will may change in the future and its dynamic, you can inject it in callback function:
$filterTotal = 480;
$filteredArray = Arr::where($myArray, function ($value, $key) use($filterTotal) {
$total = 0;
if (is_array($value) && array_key_exists('total', $value)) {
$total = intval($value['total']);
}
return ($total <= $filterTotal);
});

Group/Merge rows from two 2d arrays based on 3 identifying columns and fill missing column values with null

I'm need to merge two 2d arrays by their time, size, and type values. This should created grouped data where value_one and value_two elements may exist in the same row. If there aren't two rows to merge together, then I need the missing element to be set to null -- this way all rows will have the same elements/structure.
$array1 = [
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_one' => '66',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_one' => '43',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_one' => '23',
]
];
And
$array2 = [
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_two' => '28',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_two' => '56',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_two' => '14',
],
[
'date' => '2018-06-23',
'size' => 'S',
'type' => 'Cap',
'value_two' => '29',
]
]
Desired result:
[
[
'date' => '2018-06-23',
'size' => 'L',
'type' => 'shoes',
'value_one' => '66',
'value_two' => '28',
],
[
'date' => '2018-06-23',
'size' => 'XL',
'type' => 'shirt',
'value_one' => '43',
'value_two' => '56',
],
[
'date' => '2018-06-23',
'size' => 'M',
'type' => 'Bag',
'value_one' => '23',
'value_two' => '14',
],
[
'date' => '2018-06-23',
'size' => 'S',
'type' => 'Cap',
'value_one' => null,
'value_two' => '29',
]
]
I want to solve this case with php, laravel or collection "Laravel" class.
I tried to create the array and merge using array_merge_recursive(), array_merge(), or using this code:
foreach ($d as $k => $v) {
$new_arr[$v['date']][] = $v;
}
try
//both arrays will be merged including duplicates
$result = array_merge( $array1, $array2 );
//duplicate objects will be removed
$result = array_map("unserialize", array_unique(array_map("serialize", $result)));
//array is sorted on the bases of id
sort( $result );
For an elegant solution that only needs one loop, use the following:
Hardcode an array of default keys in your desired order.
Merge the arrays and iterate.
Identifying matching data sets by the first three elements in each row.
Depending on whether the composite key has been encountered before, overwrite the default or cached data with the current row.
To remove temporary composite key after looping, call array_values() on the result array.
Code: (Demo)
$defaults = array_fill_keys(['date', 'size', 'type', 'value_one', 'value_two'], null);
$result = [];
foreach (array_merge($array1, $array2) as $row) {
$compositeKey = implode('_', array_slice($row, 0, 3));
$result[$compositeKey] = array_merge($result[$compositeKey] ?? $defaults, $row);
}
var_export(array_values($result));
You can try this
$Array_final= [];
foreach ($Array_one as $key1 => $value1) {
foreach ($Array_two as $key2 => $value2) {
if ($value1['date']==$value2['date']) {
$Array_final[]=$value2+$value1;
}
}
}
You can try this :-
$final = $arr1; // default get all values from first array
foreach ($arr2 as $value) { // loop through second array to match
$flag = 0;
foreach ($final as $key => $data) {
// Check for date, size and type
if ($data['date']===$value['date'] && $data['size']===$value['size'] && $data['type']===$value['type']) {
$final[$key]['value_two'] = $value['value_two'];
$flag = 1;
break;
}
}
if ($flag === 0) { // If similar not found, then add new one
array_push($final, $value);
}
}
print_r($final);
Output :-
Array
(
[0] => Array
(
[date] => 2018-06-23
[size] => L
[type] => shoes
[value_one] => 66
[value_two] => 28
)
[1] => Array
(
[date] => 2018-06-23
[size] => XL
[type] => shirt
[value_one] => 43
[value_two] => 56
)
[2] => Array
(
[date] => 2018-06-23
[size] => M
[type] => Bag
[value_one] => 23
[value_two] => 14
)
[3] => Array
(
[date] => 2018-06-23
[size] => S
[type] => Cap
[value_two] => 29
)
)
Fiddle link :- https://3v4l.org/fSh1V
try
var result = a1.slice(0);
for (var i = 0 ; i < result.length ; i++){
for (var j = 0; j < a2.length ; j++){
if (result[i]. date == a2[j]. date && result[i]. size == a2[j]. size && result[i]. type == a2[j]. type){
result[i]. value_one = a2[j]. value_one;
result[i]. value_two = a2[j].value_two;
}
};
};
console.log(result);

Counting occurrences in an array that has more than 1 key

I'm trying to get the occurrences of an array taking in count 1 key value, for example:
$newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-13'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];
I want to transform this, to something like this:
Array ( [0] => Array ( [id] => 1 [date] => 2016-03-11 [occurences] => 2 ) [1] => Array ( [id] => 2 [date] => 2016-04-22 [occurences] => 4 ) )
I tried doing this:
$cleanarray;
$newarray2=$newarray;
$newarray;
$k=0;
$num=1;
for($i=0; $i<count($newarray); $i++){
for($j=1; $j<count($newarray2); $j++){
if($newarray2[$j]["id"]==$newarray[$i]["id"]){
$num++;
}
}
$cleanarray[$k] = [
'id' => $newarray[$i]["id"],
'date' => $newarray[$i]["date"],
'occurences' => $num
];
$k++;
$num=0;
}
But a lot of items repeat, with the same occurrences but several times, and in other cases the repeated items (with same id) would have different occurrences, so I don't know what can I do, I know that there is a function of:
$occurences = array_count_values($array);
But it doesn't work in this case, how can I approach to the solution?
I know what are you looking for, but I think this could solve your problems:
$newarray[0] = [
'id' => '2',
'date' => '2016-04-22'
];
$newarray[1] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[2] = [
'id' => '2',
'date' => '2016-04-12'
];
$newarray[3] = [
'id' => '1',
'date' => '2016-03-11'
];
$newarray[4] = [
'id' => '2',
'date' => '2016-03-05'
];
$newarray[5] = [
'id' => '1',
'date' => '2016-03-01'
];
foreach($newarray as $key => $value){
if(isset($found[$value['id']][$value['date']])) {
$found[$value['id']][$value['date']]++;
} else {
$found[$value['id']][$value['date']] = 1;
}
}
print_r($found);
this will return something like:-
Array
(
[2] => Array
(
[2016-04-22] => 1
[2016-04-12] => 2
[2016-03-05] => 1
)
[1] => Array
(
[2016-03-11] => 1
[2016-03-01] => 1
)
)
Using temporary keys for this process will be the most performant way. Temporary keys simplify the output array task, requiring less and faster checking. If you wish to sort on id after the result array is generated, the temporary keys allow a simple ksort() call.
Code: (Demo)
$newarray=[
['id' => '2','date' => '2016-04-22'],
['id' => '2','date' => '2016-04-13'],
['id' => '2','date' => '2016-04-12'],
['id' => '1','date' => '2016-03-11'],
['id' => '2','date' => '2016-03-05'],
['id' => '1','date' => '2016-03-01']
];
foreach($newarray as $a){
if(!isset($result[$a['id']])){
$result[$a['id']]=array_merge($a,['occurrences'=>1]); // use id as temp key, preserve first found date
}else{
++$result[$a['id']]['occurrences']; // only update occurrences to preserve date
}
}
ksort($result); // optionally sort on id ASC
var_export(array_values($result)); // remove temporary keys from first level and print to screen
Output:
array (
0 =>
array (
'id' => '1',
'date' => '2016-03-11',
'occurrences' => 2,
),
1 =>
array (
'id' => '2',
'date' => '2016-04-22',
'occurrences' => 4,
),
)
You can do it like below:-
$final_array = array();
foreach($newarray as $arr){
if(!in_array($arr['id'],array_keys($final_array))){
$final_array[$arr['id']] = $arr;
$final_array[$arr['id']]['occurences'] = 1;
}else{
$final_array[$arr['id']]['occurences'] += 1;
}
}
$final_array= array_values($final_array);
print_r($final_array);
Output:- https://eval.in/847242
Note:- if you want final array to be ascending order of id then use usort() function like below:-
function cmpId($a, $b) {
return ($a['id'] - $b['id']);
}
usort($final_array, "cmpId");
print_r($final_array);
Output:- https://eval.in/847245

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

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

Merge two Arrays by Values

I have this Array:
$mergedItems = array(
0 => array(
'id_item' => 'AZ-110'
'amount' => 12
),
1 => array(
'id_item' => 'BZ-110',
'amount' => 13
),
2 => array(
'id_item' => 'BZ-210',
'amount' => 28
),
3 => array(
'id_item' => 'CZ-291',
'amount' => 11
)
);
AND this Array:
$items = array(
0 => array(
'number' => 'AZ-110'
),
1 => array(
'number' => 'BZ-110'
),
2 => array(
'number' => 'CZ-291'
),
3 => array(
'number' => 'BZ-210'
)
);
Now what i want is to order the first array by the id_item Value to match the same order than the 2nd one by its values.
The resulting array has to include all values of the 2nd array AND the belonging amount-value of the first array. The Keys must not be kept!
I can't use array_merge since the 2nd Array has a dynamic amount of more items, so i only want all items from the second Array that are set in the first one.
Does anyone get what i mean? I am searching for a quick and non-dirty way to get this result as expected.
/Edit:
Expected Array:
$detailedItems = array(
0 => array(
'number' => 'AZ-110',
'amount' => 12
),
1 => array(
'number' => 'BZ-110',
'amount' => 13
),
2 => array(
'number' => 'CZ-291',
'amount' => 11
),
3 => array(
'number' => 'BZ-210',
'amount' => 28
)
);
A PHP 5.5 solution:
$itemMap = array_flip(array_column($mergedItems, 'id_item'));
$result = array_map(
function($i) use($itemMap, $mergedItems) {
return $mergedItems[$itemMap[$i['number']]];
},
$items);
print_r($result);
For 5.3 <= PHP < 5.5 you can simply substitute array_map for array_column:
$itemMap = array_flip(array_map(
function($i) { return $i['id_item']; },
$mergedItems));
How it works
The idea is to create a map of item numbers to indexes inside $mergedItems, ie.
[
'AZ-100' => 0,
'BZ-110' => 1,
'BZ-210' => 2,
// etc
]
With this information at hand it's very easy to iterate over $items (so that the result will be ordered based on that array) and pick the appropriate element from $mergedItems to append to the result each time.
$temp = $items;
foreach($temp as &$val)
{
foreach($mergedItems as $item)
{
if($item['id_item'] == $val['number'])
{
$val['amount'] = $item['amount'];
break;
}
}
}
print_r($temp);
There isn't really a "non-dirty" (meaning single line) way to do this as far as I know, but this function should work:
$out = array();
foreach ($mergedItems as $key => $value) {
if (array_key_exists($key, $detailedItems)) { // Make sure it exists to prevent errors
$out[$key] = $detailedItems[$key] + array('amount' => $value['amount']);
} else {
$out[$key] = $value['amount'];
}
}
print_r($out);
You can try following codes:
foreach ($mergedItems as $item) {
$merged[$item['id_item']] = array('amount' => $item['amount']);
}
foreach ($items as $item)
{
$detailedItems[] = array_merge($item, $merged[$item['number']]);
}
Output
var_dump($detailedItems);
array (size=4)
0 =>
array (size=2)
'number' => string 'AZ-110' (length=6)
'amount' => int 12
1 =>
array (size=2)
'number' => string 'BZ-110' (length=6)
'amount' => int 13
2 =>
array (size=2)
'number' => string 'CZ-291' (length=6)
'amount' => int 11
3 =>
array (size=2)
'number' => string 'BZ-210' (length=6)
'amount' => int 28

Categories