I am having some trouble while trying to compare two plucked collections. Objective is to compare the plucked values and get those values that are not present in both arrays.
I tried the following for this
$users = message::withTrashed()->where([
'sentTo' => $authId,
'isDraft' => 0
])->groupBy('group_message_id')->pluck('group_message_id')->all();
$checkDeleted = inboxDeleted::whereIn('thread_id',$users)
->where('user_id',$authId)
->pluck('thread_id')->all();
From here same values should be eliminated and distinct values should be kept. Is it possible to compare plucked values? If no then how to check the plucked values.
Data should not be fetched from query?
Thanks for suggestions. :)
You can use diff() (Laravel solution):
$diff = $users->diff($checkDeleted);
$diff->all();
From the docs:
The diff method compares the collection against another collection or a plain PHP array based on its values. This method will return the values in the original collection that are not present in the given collection
As I know, pluck returns values of particular column as array instead of collection.
So, you can use array_diff() method like this:
$difference = array_diff($users,$checkDeleted);
This will give you desired result.
You can use
$result=array_diff($a1,$a2);
Related
Database table SITE has many columns. One of them is site_id. I need all the site_ids as an array since it has to be fed to a method which accepts only a string array.
What I tried so far is:
$sites = DB::select('select site_id from site_tab');
$sites_arr = $sites->toArray();
But this doesn't produce the result I want. I need $sites_arr to be like ['A','B','C',...]
Please suggest a way to get this done. A solution based on Eloquent is also OK for me.
Thanks
Try this:
DB::table('site_tab')->pluck('site_id')->toArray();
reference pluck
referen toArray
If you open a manual, you will see that
The select method will always return an array of results
So, there's no need to use ->toArray(), as result is already an array.
To get values as array of names you can do:
$site_ids = DB::table('site_tab')->pluck('site_id');
Using ->toArray() here is optional, as you can iterate over $site_ids (which is a Collection) with a foreach too.
Hello I would like to know is it possible to get column value as string. Instead of array in array:
Current query: Number::limit('1000')->get(['number'])->toArray()
The result at the moment is this:
Preferable result:
Before your toArray() call, add pluck('number'):
$result = Number::limit('1000')->get(['number'])->pluck('number')->toArray();
That's it! This will pluck just the number attributes from your result collection, and give you a single-level array.
The reason this works, is because you are getting a Collection back from get():
All multi-result sets returned by Eloquent are an instance of the Illuminate\Database\Eloquent\Collection object, including results retrieved via the get method or accessed via a relationship.
And the pluck method:
https://laravel.com/docs/5.1/collections#method-pluck
Update
Another, even more succinct method provided by #wunch in the comments:
$result = Number::limit('1000')->lists('number')->toArray();
Ok, I'm probably going about this in the wrong way, so before I go any further, i thought I'd check with some experts.
Previously, after searching the DB I'd create an array with the array name of the date and there would only be 1 array per date. This could then be called and displayed on the appropriate part of the calendar.
But there will now potentially be multiple entries per date and I am trying to change to a multi-dimensional array.
$stmt = $dbc->prepare("SELECT stoname, date, hours1, hours2 FROM table WHERE MONTH(date)=? AND YEAR(date)=?");
$stmt->bind_param("ss", $month, $year);
$stmt->execute();
$stmt->bind_result($sto_name, $DB_date, $hours1, $hours2);
while ($stmt->fetch())
{
//Loop through to make new array corresponding to date in database
$foo="_".str_replace("-","",$DB_date); //take the "-" outta the date
${$foo}[$sto_name]=array(
'sto_name'=>$sto_name,
'hours1'=>$hours1,
'hours2'=>$hours2);
}
$stmt->close();
I'm not sure if this is the best way, although it does seem to work ok. However, it then makes it hard to access the arrays as the [$sto_name] is unknown and it appears I can't use numeric bits to call an associative array, e.g. $20160316[0]. In the output, I'd need to check if an array exists for that date irrespective of the [$sto_name], then can foreach through to print the array.
I had thought about something like:
${$foo}=array(
array(
'sto_name'=>$sto_name,
'hours1'=>$hours1,
'hours2'=>$hours2),
);
But then on the mysqli while loop it presumably overwrites the first array if there's a second array with the same date/$foo.
As you said that:-"But then on the mysqli while loop it presumably overwrites the first array if there's a second array with the same date/$foo"
So you need to change ${$foo}[$sto_name] to ${$foo}[$sto_name][].
Or
Better would be to use ${$foo}[] instead of ${$foo}[$sto_name]
Note:- It will works fine in both condition:- Either you got single data or multiple data.
I have 3 columns id, msg and created_at in my Model table. created_at is a timestamp and id is primary key.
I also have 5 datas, world => time4, hello => time2,haha => time1,hihio => time5 and dunno => time3 and these datas are arranged in ascending order (as arranged here) based on their id.
In laravel 4, I want to fetch these data, arrange them in ascending order and take the last n(in this case, 3) number of records. So, I want to get dunno,world and hihio rows displayed like this in a div :
dunno,time3
world,time4
hihio,time5
What I have tried
Model::orderBy('created_at','asc')->take(3);
undesired result :
haha,time1
hello,time2
dunno,time3
Also tried
Model::orderBy('created_at','desc')->take(3);
undesired result :
hihio,time5
world,time4
dunno,time3
I have also tried the reverse with no luck
Model::take(3)->orderBy('created_at','asc');
This problem seems fairly simple but I just can't seem to get my logic right. I'm still fairly new in Laravel 4 so I would give bonus points to better solutions than using orderBy() and take() if there is. Thank you very much!
You are very close.
It sounds like you want to first order the array by descending order
Model::orderBy('created_at','desc')->take(3);
but then reverse the array. You can do this one of two ways, either the traditional PHP (using array_reverse).
$_dates = Model::orderBy('created_at','desc')->take(3);
$dates = array_reverse($_dates);
Or the laravel way, using the reverse function in Laravel's Collection class.
$_dates = Model::orderBy('created_at','desc')->take(3)->reverse();
Check out Laravel's Collection documentation at their API site at http://laravel.com/api/class-Illuminate.Support.Collection.html
Now $dates will contain the output you desire.
dunno,time3
world,time4
hihio,time5
You're pretty close with your second attempt. After retrieving the rows from the database, you just need to reverse the array. Assuming you have an instance of Illuminate\Support\Collection, you just need to the following:
$expectedResult = $collection->reverse();
To get last three rows in ascending order:
$_dates = Model::orderBy('created_at','desc')->take(3)->reverse();
Now, the json output of $_dates will give you a object of objects.
To get array of objects use:
$_dates = Model::orderBy('created_at','desc')->take(3)->reverse()->values();
$reverse = Model::orderBy('created_at','desc')->take(3);
$show = $reverse->reverse();
I have 2 arrays one retrieved from a database (saved results) and the other from an xml (new results)
$fromDB = array('123','124','524','15','616');
$fromXML = array('123','124','524','15','818');
I want to compare those two and see which values are old (fromDB) and which are new (fromXML) so to insert the old value in a different table.
How can i achieve this?
The array_diff function is what you're looking for.
Take a look at the array_diff() function