Related
I'm trying to write an excel from a laravel controller where i have all the data in an array, and i managed to write it, but i have to format it now, this is the array that i have:
[2020-12-30 13:22:05] local.DEBUG: array (
0 =>
array (
0 => '1',
1 => '2',
),
1 =>
array (
0 => 'Test Name 1',
1 => 'Test Name 2',
),
2 =>
array (
0 => 'user',
1 => 'user2',
),
3 =>
array (
0 => '1',
1 => '2',
),
)
This is the way i'm creating the Excel:
Excel::create('Filename', function($excel) use ($budgets) {
$excel->sheet('Sheetname', function($sheet) use ($budgets) { //$budgets is the array i'm printing on Log
$sheet->fromArray($budgets);
});
})->export('xls');
And this is the way that my excel is printing it:
1
2
Test Name 1
Test Name 2
user1
user2
1
2
And the way i want to print it is:
Code
Name
User
Number
1
Test Name 1
user1
1
2
Test Name 2
user2
2
But i don't know how to achieve this. Can anyone help me with this?
//edits//
I added some code to re estructure the array, now i have this:
$users = ['Code', 'Name', 'User', 'Number'];
for ($i=0; $i<count($code); $i++){
array_push($users, array($code[$i], $name[$i], $user[$i], $number[$i]));
}
Log::debug($users);
And this is the Log:
[2020-12-30 15:17:40] local.DEBUG: array (
0 => 'Code',
1 => 'Name',
2 => 'User',
3 => 'Number',
4 =>
array (
0 => '1',
1 => 'Test Name 1',
2 => 'user1',
3 => '1',
),
5 =>
array (
0 => '2',
1 => 'Test Name 2',
2 => 'user2',
3 => '2',
),
)
But i'm getting this error:
[message] => Row `Code` must be array.
[class] => PHPExcel_Exception
You will could re-structure your array.
To get the print you want array should look like:
$budget = [
['Code', 'Name', 'User', 'Number'],
[1, 'Test Name 1', 'user1', 1],
...
];
Ok, so, i managed to re-structure the array and getting the Excel the way i wanted doing this:
public function generateExcel(Request $request)
{
$code = $request->input('code');
$name = $request->input('name');
$user = $request->input('user');
$number = $request->input('number');
$users = array();
array_push($users, array('Code', 'Name', 'User', 'Number'));
for ($i=0; $i<count($code); $i++){
array_push($users, array($code[$i], $name[$i], $user[$i], $number[$i]));
}
Excel::create('Filename', function($excel) use ($users) {
$excel->sheet('Sheetname', function($sheet) use ($users) {
$sheet->fromArray($users);
});
})->export('xls');
return true;
I have below two dimentional array
$data = [
['category'=>1,'attribute'=>1,'option'=>1],
['category'=>1,'attribute'=>1,'option'=>2],
['category'=>1,'attribute'=>2,'option'=>3],
['category'=>1,'attribute'=>2,'option'=>4],
['category'=>2,'attribute'=>3,'option'=>5],
['category'=>2,'attribute'=>3,'option'=>6],
['category'=>2,'attribute'=>4,'option'=>7],
['category'=>2,'attribute'=>4,'option'=>8]
];
And I want to convert this array into Three dimentional according to Parent-Child value like below array.
$data = [
'1'=>[
'1' => [
'1' => 1,
'2' => 2
],
'2' => [
'3' => 3,
'4' => 4
]
],
'2'=>[
'3' => [
'5' => 5,
'6' => 6
],
'4' => [
'7' => 7,
'8' => 8
]
],
];
In this first iterator is value of 'category' key which iterate two times. second iteration is for 'attribute' and likewise third is for 'option', which iterate 8 times.
Addition: What if I want to do reverse. I have second array and want to convert in first one.
Thanks.
$arr = [
['category'=>1,'attribute'=>1,'option'=>1],
['category'=>1,'attribute'=>1,'option'=>2],
['category'=>1,'attribute'=>2,'option'=>3],
['category'=>1,'attribute'=>2,'option'=>4],
['category'=>2,'attribute'=>3,'option'=>5],
['category'=>2,'attribute'=>3,'option'=>6],
['category'=>2,'attribute'=>4,'option'=>7],
['category'=>2,'attribute'=>4,'option'=>8],
];
$newArr = [];
foreach($arr as $arrRow) {
$newArr[$arrRow['category']][$arrRow['attribute']][$arrRow['option']] = $arrRow['option'];
}
Strings with numbers for array keys will be converted to int in PHP.
** I have edited this to show how I got my code to work using array_search
I have an array, $arr1 with 5 columns as such:
key id name style age whim
0 14 bob big 33 no
1 72 jill big 22 yes
2 39 sue yes 111 yes
3 994 lucy small 23 no
4 15 sis med 24 no
5 16 maj med 87 yes
6 879 Ike larg 56 no
7 286 Jed big 23 yes
This array is in a cache, not a database.
I then have a second array with a list of id values -
$arr2 = array(0=>14, 1=>72, 2=>8790)
How do I filter $arr1 so it returns only the rows with the id values in $arr2?
I got my code to work as follows:
$arr1 = new CachedStuff(); // get cache
$resultingArray = []; // create an empty array to hold rows
$filter_function = function ($row) use ($arr2) {
return (array_search($row['id'], $arr2));
};
$resultingArrayIDs = $arr1->GetIds($filter_function, $resultingArray);
This gives me two outputs: $resultingArray & $resultingArrayIDs both of which represent the intersection of the $arr1 and $arr2.
This whole task can be accomplished with just one slick, native function call -- array_uintersect().
Because the two compared parameters in the custom callback may come either input array, try to access from the id column and if there isn't one declered, then fallback to the parameter's value.
Under the hood, this function performs sorting while evaluating as a means to improve execution time / processing speed. I expect this approach to outperform iterated calls of in_array() purely from a point of minimized function calls.
Code: (Demo)
var_export(
array_uintersect(
$arr1,
$arr2,
fn($a, $b) =>
($a['id'] ?? $a)
<=>
($b['id'] ?? $b)
)
);
Something like this should do it, provided I've understood your question and data structure correctly:
$dataArray = [
[ 'key' => 0, 'id' => 14 , 'name' => 'bob' , 'style' => 'big' , 'age' => 33 , 'whim' => 'no' ],
[ 'key' => 1, 'id' => 72 , 'name' => 'jill' , 'style' => 'big' , 'age' => 22 , 'whim' => 'yes' ],
[ 'key' => 2, 'id' => 39 , 'name' => 'sue' , 'style' => 'yes' , 'age' => 111 , 'whim' => 'yes' ],
[ 'key' => 3, 'id' => 994 , 'name' => 'lucy' , 'style' => 'small' , 'age' => 23 , 'whim' => 'no' ],
[ 'key' => 4, 'id' => 15 , 'name' => 'sis' , 'style' => 'med' , 'age' => 24 , 'whim' => 'no' ],
[ 'key' => 5, 'id' => 16 , 'name' => 'maj' , 'style' => 'med' , 'age' => 87 , 'whim' => 'yes' ],
[ 'key' => 6, 'id' => 879 , 'name' => 'Ike' , 'style' => 'larg' , 'age' => 56 , 'whim' => 'no' ],
[ 'key' => 7, 'id' => 286 , 'name' => 'Jed' , 'style' => 'big' , 'age' => 23 , 'whim' => 'yes' ]
];
$filterArray = [14, 72, 879];
$resultArray = array_filter( $dataArray, function( $row ) use ( $filterArray ) {
return in_array( $row[ 'id' ], $filterArray );
} );
View this example on eval.in
However, your question appears to suggest this data might be coming from a database; is that correct? If so, perhaps it's more efficient to pre-filter the results at the database-level. Either by adding a field in the SELECT query, that represents a boolean value whether a row matched your filter ids, or by simply not returning the other rows at all.
One way is with foreach loop with array_search()
$result = [];
foreach ($arr1 as $value) { // Loop thru $arr1
if (array_search($value['id'], $arr2) !== false) { // Check if id is in $arr2
$result[] = $value; // Push to result if true
}
}
// print result
print_r($result);
As #DecentDabbler mentioned - if the data is coming out of a database, using an IN on your WHERE will allow you to retrieve only the relevant data.
Another way to filter is to use array functions
array_column extracts the value of the id column into an array
array_intersect returns the elements which are in both $arr1['id'] and $arr2
array_flip flips the resulting array such that the indices into $arr1 indicate the elements in both $arr1 and $arr2
$arr1 = [ [ 'id' => 14, 'name' => 'bob'],
['id' => 72, 'name' => 'jill'],
['id' => 39, 'name' => 'sue'],
['id' => 994, 'name' => 'lucy'],
['id' => 879, 'name'=> 'large']];
$arr2 = [ 14,72,879 ];
$intersection = array_flip(array_intersect(array_column($arr1,'id'),$arr2));
foreach ($intersection as $i) {
var_dump($arr1[$i]);;
}
I have different arrays as follows:-
$reservations = ['reservationid' => '1', 'reservationid' => '2', 'reservationid' => '3']
$reservedrooms = ['reservationid'=> '1', 'roomno' => '1', 'reservationid' => '1', 'roomid'=>'2', 'reservationid' => '2', 'roomid'=>'3']
$guestdata = ['reservationid'=> '1', 'guestname' => 'Adam', 'reservationid' => '1', 'guestname'=>'Abraham', 'reservationid' => '2', 'guestname'=>'David']
How to join them so that they can be used as nested array with similar reservationids in CodeIgniter? I have also sent it to client side using Json and be depicted in JQuery Datatables. How to achieve it logically?
I have following code which is running on multiple tables
$this->db->from('hotelbrancheshasreservations');
$this->db->join('reservation', 'reservation.reservationid = hotelbrancheshasreservations.reservations_reservationsid');
$this->db->join('reservedrooms', 'reservedrooms.reservation_reservationid = hotelbrancheshasreservations.reservations_reservationsid');
$this->db->where( array('hotelbranches_hotelbranchesid'=>$branchid, 'status'=>$status));
$reservations = $this->db->get()->result_array();
I want result array as follows:-
$result = array (
"reservationid" => '1', 'rooms' => Array(
"roomno" => '1',
"roomno" => '2'), 'guests' => Array('guestid' => '1', 'guestname' => 'Adam', 'guestid' => '2', 'guestname' => 'David',) );
The following code is run in model class and then is returned back to controller. Then controller echos json object array to client side.
$this->$db->trans_start();
$this->$db->from('hotelbrancheshasreservations');
$this->$db->join('reservation', 'reservation.reservationid = hotelbrancheshasreservations.reservations_reservationsid');
$this->$db->join('reservedrooms', 'reservedrooms.reservation_reservationid = hotelbrancheshasreservations.reservations_reservationsid');
$this->$db->where( array('hotelbranches_hotelbranchesid'=>$branchid, 'status'=>$status));
$reservations = $this->$db->get()->result_array();
$this->$db->trans_complete();
return $reservations;
The above code returned following array after joining and in this solution problem is that if a reservation has more than one reserved rooms then that row is included in result set for multiple times and thats why i need to nest the reserved rooms in reservation array.
following is result set:
{"data":[{"hotelbrancheshasreservationsid":"18","hotelbranches_hotelbranchesid":"1","reservations_reservationsid":"KHAN2016Q221","status":"active","tblid":"19","reservationid":"KHAN2016Q221","startdate":"2016-05-16 11:59:00","enddate":"2016-05-21 11:59:00","duration":"","noofroom":"","reservationdate":"2016-05-22 01:41:32","guestarrivaldate":"0000-00-00 00:00:00","gestdeparturedate":"0000-00-00 00:00:00","totalreservedadults":"","totalreservedchilds":"","totalreservationcharges":"","createdby":"","createdon":"0000-00-00 00:00:00","lastmodifiedby":"","lastmodifiedon":"0000-00-00 00:00:00","reservedroomsid":"1","reservation_reservationid":"KHAN2016Q221","hotelrooms_hotelroomsid":"1"},{"hotelbrancheshasreservationsid":"145","hotelbranches_hotelbranchesid":"1","reservations_reservationsid":"KHAN2016Q3-34","status":"active","tblid":"146","reservationid":"KHAN2016Q3-34","startdate":"2016-07-24 00:22:31","enddate":"2016-07-25 00:22:37","duration":"1 days 6 seconds ","noofroom":"2","reservationdate":"2016-07-24 00:26:51","guestarrivaldate":"2016-07-24 00:26:30","gestdeparturedate":"2016-07-25 00:26:35","totalreservedadults":"2","totalreservedchilds":"2","totalreservationcharges":"1200","createdby":"1","createdon":"2016-07-24 00:23:05","lastmodifiedby":"","lastmodifiedon":"0000-00-00 00:00:00","reservedroomsid":"91","reservation_reservationid":"KHAN2016Q3-34","hotelrooms_hotelroomsid":"2"},{"hotelbrancheshasreservationsid":"145","hotelbranches_hotelbranchesid":"1","reservations_reservationsid":"KHAN2016Q3-34","status":"active","tblid":"146","reservationid":"KHAN2016Q3-34","startdate":"2016-07-24 00:22:31","enddate":"2016-07-25 00:22:37","duration":"1 days 6 seconds ","noofroom":"2","reservationdate":"2016-07-24 00:26:51","guestarrivaldate":"2016-07-24 00:26:30","gestdeparturedate":"2016-07-25 00:26:35","totalreservedadults":"2","totalreservedchilds":"2","totalreservationcharges":"1200","createdby":"1","createdon":"2016-07-24 00:23:15","lastmodifiedby":"","lastmodifiedon":"0000-00-00 00:00:00","reservedroomsid":"92","reservation_reservationid":"KHAN2016Q3-34","hotelrooms_hotelroomsid":"1"},{"hotelbrancheshasreservationsid":"146","hotelbranches_hotelbranchesid":"1","reservations_reservationsid":"KHAN2016Q3-35","status":"active","tblid":"147","reservationid":"KHAN2016Q3-35","startdate":"2016-07-25 22:05:36","enddate":"2016-07-26 22:05:41","duration":"1 days 5 seconds ","noofroom":"1","reservationdate":"2016-07-25 22:08:07","guestarrivaldate":"2016-07-25 22:07:53","gestdeparturedate":"2016-07-26 22:07:57","totalreservedadults":"1","totalreservedchilds":"","totalreservationcharges":"1500","createdby":"1","createdon":"2016-07-25 22:05:52","lastmodifiedby":"","lastmodifiedon":"0000-00-00 00:00:00","reservedroomsid":"93","reservation_reservationid":"KHAN2016Q3-35","hotelrooms_hotelroomsid":"4"},{"hotelbrancheshasreservationsid":"147","hotelbranches_hotelbranchesid":"1","reservations_reservationsid":"KHAN2016Q3-36","status":"active","tblid":"148","reservationid":"KHAN2016Q3-36","startdate":"2016-07-26 10:54:05","enddate":"2016-07-27 10:54:10","duration":"1 days 5 seconds ","noofroom":"1","reservationdate":"2016-07-26 10:56:15","guestarrivaldate":"2016-07-26 10:55:58","gestdeparturedate":"2016-07-27 10:56:03","totalreservedadults":"1","totalreservedchilds":"","totalreservationcharges":"700","createdby":"1","createdon":"2016-07-26 10:54:28","lastmodifiedby":"","lastmodifiedon":"0000-00-00 00:00:00","reservedroomsid":"94","reservation_reservationid":"KHAN2016Q3-36","hotelrooms_hotelroomsid":"3"}]}
I use the sync function for syncing a belongsToMany Relation:
$model->products()->sync($productIds);
In the $productIds array there is flat array with some Id's -
something like this:
$productIds = [1,3,5,6];
What I want:
The pivot table has also additional columns like "created_by" and "updated_by".
But how can I add these fields to my array WITHOUT doing a foreach loop?
Is there a shorter way to do this?
I need an array like this:
$productIds = [1 => [
'created_by' => 1,
'updated_by' => 1
],3 => [
'created_by' => 1,
'updated_by' => 1
],5 => [
'created_by' => 1,
'updated_by' => 1
],6 => [
'created_by' => 1,
'updated_by' => 1
]];
Yes I know I can do it with foreach and add the columns while I loop through the array. But I want do it shorter.. is there a way to do it shorter (perhaps with laravel)?
It should be enough to pass what you have set in $productIds in your code example to sync().
This method works not only with array of integers. You can also pass an array where key is the synced ID and value is the array of pivot attributes that should be set for given ID.
This should do the trick:
$productIds = [
1 => [
'created_by' => 1,
'updated_by' => 1
]
//rest of array
];
$model->products()->sync($productIds);
Just make sure you have defined those fields as pivot fields in your relation definition.
In order to generate such table based on a list of IDs in $productIds you can do the following:
$productIds = array_fill_keys($productIds, array(
'created_by' => 1,
'updated_by' => 1,
));