I am trying to achieve something like this:
I am using Laravel, and for example to display the results I would do a foreach on the array and display the title, the body etc.
Example
#foreach($resArray as $res)
{{$res->Title}}
#endforeach
And that will display the title of each result in the array, I also have the date in $res->startDate but I am not sure how to list each result with same date under their specific date.
You probably didn't understood..
So for example if I have two notifications from 10/07/2017 and one from 11/07/2017 they will display as this:
10/07/2017
- notification 1
- notification 2
11/07/2017
- notification
I was thinking at an if statement but what statement
if($res->startDate) what so this won't work either, I was thinking to store them in arrays, for example array of date 11/07/2017 and display those arrays but would that even work...
Couldn't find too much from google as I am not too sure how to google this in a good maneer.
EDIT 1
I tried doing this:
$notifResult = notifications::where('userID', '=', $userID)->select('*')->groupBy(['date'])->get();
dd($notifResult);
but it didn't work, first of all, I had 3 results in database, it only got 2 of them and it didn't even group them by date, the two results that are listed before are from different days...
EDIT 2
I added toArray to it and this is what I've got:
still, it only picks two results...
One naive but simple solution is to sort the results by start date and then in the foreach check if the previous date (store it in temp var) is different from the current one, and if true display the new date.
$prevDate = '';
#foreach($resArray as $res)
#if($prevDate != '' && $prevDate != $res->startDate) {
//do sth to break the html and display the new date
#endif
{{$res->Title}}
{{$prevDate = $res->startDate;}}
#endforeach
if i understand your problem you must use group by
$collection = collect([
['date' => '10/07/2017', 'title' => 'notification 1'],
['date' => '10/07/2017', 'title' => 'notification 2'],
['date' => '11/07/2017', 'title' => 'notification'],
]);
$grouped = $collection->groupBy('date');
$grouped->toArray();
dd($grouped);
Related
EDIT:
I want to thanks #jimmix for giving me some idea to get started on my last post, But unfortunately, my post was put on hold. Due to the lack of details.
But here are the real scenario, I'm sorry if I didn't explain well my question.
From my CSV file, I have a raw data, then I will upload using my upload() function in into my phpmyadmin database with the table name "tbldumpbio",
See the table structure below:(tbldumpbio)
From my table tbldumpbio data, I have a function called processTimesheet()
Here's the code:
public function processTimesheet(){
$this->load->model('dbquery');
$query = $this->db->query("SELECT * FROM tbldumpbio");
foreach ($query->result() as $row){
$dateTimeExplArr = explode(' ', $row->datetimex);
$dateStr = $dateTimeExplArr[0];
$timeStr = $dateTimeExplArr[1];
if($row->status='C/Out' and !isset($timeStr) || empty($timeStr) ){
$timeStrOut ='';
} else {
$timeStrOut = $dateTimeExplArr[1];
}
if($row->status='C/In' and !isset($timeStr) || empty($timeStr) ){
$timeStrIn ='';
} else {
$timeStrIn = $dateTimeExplArr[1];
}
$data = array(
'ID' => '',
'companyAccessID' => '',
'name' => $row->name,
'empCompID' => $row->empid,
'date' => $dateStr,
'timeIn' => $timeStrIn,
'timeOut' => $timeStrOut,
'status' => '',
'inputType' => ''
);
$this->dbquery->modInsertval('tblempbioupload',$data);
}
}
This function will add another data into another table called "tblempbioupload". But here are the results that I'm getting with:
Please see the below data:(tblempbioupload)
The problem is:
the date should not be duplicated
Time In data should be added if the status is 'C/In'
Time Out data should be added if the status is 'C/Out'
The expected result should be something like this:
The first problem I see is that you have a time expressed as 15:xx:yy PM, which is an ambiguous format, as one can write 15:xx:yy AM and that would not be a valid time.
That said, if what you want is that every time the date changes a row should be written, you should do just that: store the previous date in a variable, then when you move to the next record in the source table, you compare the date with the previous one and if they differ, then you insert the row, otherwise you simply progress reading the next bit of data.
Remember that this approach works only if you're certain that the input rows are in exact order, which means ordered by EmpCompId first and then by date and then by time; if they aren't this procedure doesn't work properly.
I would probably try another approach: if (but this is not clear from your question) only one row per empcompid and date should be present, i would do a grouping query on the source table, finding the minimum entrance time, another one to find the maximum exit date, and use both of them as a source for the insert query.
I have this following Yii 2 query
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->all();
So imagine this query was an array. Everything found by this query has an "id" attribute.
Since it's sorted by "totals", I essentially want to return the position in the array where I can find this specific id.
Currently, I'm using this code.
foreach ($find as $t) {
$arr[] = $t->id;
if ($t->id == $id) {
break;
}
}
$key = count($arr);
return $key;
However, this code is vany wayow on a 100k+ result query.
Is there anyway to speed this up?
You could get the result as an array (instead of object) as
$find = People::find()->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
then you could find your value using array_search()
$my_index = array_search($id,$find);
but for 100k+ you should find using a direct select in db...instead tha looping on php or load all in php and scan with array_search()
To get array from query in YII, you can use queryAll();
$find = People::find()->where(['c_id' => $c_id])->orderBy('totals DESC, id DESC')->queryAll();
OR, another way to convert the object into an array is:
$find = json_decode(json_encode($find), true); // to convert all data into array.
And once you get results in array, you can implement the actual code for your requirement as given below.
You can use array_search() function to get index of your value.
$a=array("a"=>"red","b"=>"green","c"=>"blue");
echo array_search("red",$a);
The array_search() function search an array for a value and returns the key.
Maybe I didn't understand you correctly but I assume that you are trying to detect the index or key for your desired id inside an array returned from an SQL query that is sorted by some other column like total.
So let us fetch records from the database with your query with a little change asArray() like this
$find = People::find()
->where(['c_id' => $c_id])
->orderBy('totals DESC, id DESC')
->asArray()
->all();
in the result, let us assume the People table returns you an array with the following dataset ordered by columns total and id DESC.
[
0 => [
'id' => 2 ,
'c_id'=>2,
'name' => 'John' ,
'age'=>18,
'totals'=>100,
],
1=>[
'id'=>1,
'c_id'=>55,
'name'=>'Bob',
'age'=>20,
'totals'=>80,
],
2=>[
'id'=>3,
'c_id'=>85,
'name'=>'Peter',
'age'=>15,
'totals'=>75,
]
];
Now if you look into \yii\helpers\ArrayHelper you will find ArrayHelper::getColumn().
Let us use this on the array we received from the query, I assume that you are searching $id inside the column id so we will first filter out the id column like below.
$idsArray = ArrayHelper::getColumn($find, 'id');
this will give us the ids in the following sequence which is in the same order as the initial result set.
[2,1,3]
then lets use the built-in php function array_search()
$key=array_search($yourId,$idsArray);
Hope this is what you are looking for.
I have a field called "arrivalDate" and this field is a string. Each document has an arrivalDate in string format (ex: 20110128). I want my output to be something like this (date and the number of records that have that date):
Date : how many records have that date
20110105 : 5 records
20120501 : 2 records
20120602 : 15 records
I already have the query to get these results.
I am trying to display aggregated results in PHP from Elasticsearch. I want my output to be something like this:
Date : how many records have that date
20110105 : 5 records
20120501 : 2 records
20120602 : 15 records
This is what I have so far:
$json = '{"aggs": { "group_by_date": { "terms": { "field": "arrivalDate" } } } }';
$params = [
'index' => 'pickups',
'type' => 'external',
'body' => $json
];
$results = $es->search($params);
However, I don't know how to display the results in PHP. For example, if I wanted to display the total number of documents I would do echo $results['hits']['total'] How could I display all the dates with the number of records they have in PHP?
I'd suggest using aggregations in the same way you construct the query, from my experience it seems to work quicker. Please see the below code:
'aggs' => [
'group_by_date' => [
'terms' => [
'field' => 'arrivalDate',
'size' => 500
]
]
]
Following that, instead of using the typical results['hits']['hits'] you would switch out the hits parts to results['aggregations']. Then access the returning data by accessing the buckets in the response.
For accessing the data from the aggregation shown above, it would likely be something along the lines of:
foreach ($results as $result){
foreach($result['buckets'] as $record){
echo($record['key']);
}
}
There will be a better way of accessing the array within the array, however, the above loop system works well for me. If you have any issues with accessing the data, let me know.
I am using Laravel Collections methods and am trying to key my query results (which are a collection) by the id. The problem is I have multiple entries with the same id, but point to different countries and I want to have all of the values, not just the last one.
Here is my code that i am using so far:
$allCountries = new Collection($allCountries);
$offerCountries = $allCountries->keyBy('id');
dd($offerCountries);
foreach ($offer as $o) {
$o->countries = $allCountries->get($o->id);
}
To explain, my query puts the results in $allCountries which contains ids and countries and those results looks something like this
id=>225, country=>US
id=>225, country=>IT
id=>3304, country=>NZ
Just to give you a quick idea. I want to key this by the id which results in $offerCountries. I then loop thru a previous Collection that contains offers which have a certain ID that relates to the country result by id. So for the offer 225, the countries it contains are US and IT. I loop thru each offer and set the countries object equal to all the $allCountries id that it equals. The problem I have here is keyBy overwrites the value and only takes the last one. I am hoping to get some results like this:
[
225 => countries: {'id' => 225, 'country' => 'US'}, {'id' =>
'225', 'country' => 'IT'}
3304 => ['id' => 3304, 'country' => 'NZ'],
]
Is there a laravel method to do this, or do I need to write my own keyBy so it does not overwrite. If so, how can I get started to write this method?
Thanks
Instead of using keyBy, use groupBy:
$countriesById = collect($allCountries)->groupBy('id');
You could use filter and create a custom filter
$filtered = $allCountries->filter(function ($item) use ($id) {
return $item->id == $id;
});
$filtered->all();
I have 2 dates (create, update) that i want to merge in a new column, selecting the newest date... how can I do it?
Here is the array creation:
$this->Message= array(
'fields' => array('Message.id','Message.type','Message.createdate','Message.updatedate'),
'conditions' => $cond);
$messages = $this->Message->find('all', $conditionsMessage);
Now I need another field (lets call it NewDate) Message.NewDate that gets the newest date from Message.createdate and Message.updatedate, so i can call it after in a view using $messages[NewDate]
Help plz...
Thx!
UPDATE:
It's not hard to loop over the array with something like
foreach($messages as $k => $m){
if(strtotime($m['Message']['updatedate']) > strtotime($m['Message']['createdate'])){
$messages[$k]['Message']['NewDate'] = $m['Message']['updatedate'];
}else{
$messages[$k]['Message']['NewDate'] = $m['Message']['createdate'];
}
}
ORIGINAL ANSWER:
I would think that your Message.updatedate would always be the newest date, so you could just select that. But assuming that's not the case for some reason, you can create a virtual field in your model:
public $virtualFields = array(
'NewDate' => "IF(Message.updatedate > Message.createdate, Message.updatedate, Message.createdate)"
);
This uses the MySQL IF() function. If you're not using MySQL you'd have to figure out how to do something similar with your database.
http://dev.mysql.com/doc/refman/5.0/en/control-flow-functions.html#function_if