Laravel collection manipulation - php

I have User model that has 2 fields: email and id
I have this query:
$users = User::all()->get();
the result will be 3 User objects in a Collection
I want to see the result as the following:
[87 => 'user#gmail.com', 92 => 'admin#gmail.com', 10 => 'super#gmail.com']
id will be the key and email will be the value.
Is that possible via Collection class to implement? thanks

Try:
$users = User::pluck('email','id');

You can achieve like this,
$users = User::pluck("email","id");
pluck() -> You may also specify how you wish the resulting collection to be keyed:
There is alternative to do this(playing with collections),
$users = User::all()->get();
$users = $users->pluck("email","id");
Give it a try, this will work.

try this
$users = User::all();
$data = array();
foreach ($users as $key) {
$data[$key->id] = $key->email;
}
print_r($data);
Good luck...

Related

Cannot access collection by properties Laravel 5.8

So I have three different arrays with the same length in the request and below is how I combine them into one collection:
$inputs = collect();
$keys = collect(['id', 'username', 'email']);
foreach ($request['ids'] as $index => $id) {
$username = $request['usernames'][$index];
$email = $request['emails'][$index];
$inputs->push($keys->combine([$id, $username, $email]));
}
The result looks correct to me:
However, I cannot access the collection when I iterate over it:
foreach ($inputs as $input) {
dd($input->id); // Property [id] does not exist on this collection instance.
}
This is the result of dd($input):
Any pointers on this problem? (Another short way to combine the arrays into one collection will also be appreciated!)
Thank you.
It is a collection and you should get it like this: dd($input['id']).
You can combine arrays bt array_merge
array_merge($a1,$a2)
or collect
$c=collect([$arr1,$arr2])
then pluck if you want
$c->pluck('username')

How to add limit to array data fetched from database in laravel

I'm retrieving the rows from user table and I'm using below code.
<?php $user = User::get(); ?>
I want to add array limit for $user data. I don't want to use paginate();. To add limit I'm using below code but it's not working
$users = array_slice($users, 0,2);
But it's showing below error message
exception 'ErrorException' with message 'array_slice() expects
parameter 1 to be array, object given' in........
How to I add limit to $user?
<?php
$user = User::get();
$user = $user ->limit(10);
?>
try limit or
<?php
$user = User::get();
$user = $user ->take(10);
?>
In recent Laravel versions you can also use:
User::limit(10)->offset(0)->get();
Note that User model must extend Eloquent.
Do you mean to use:
$users = array_slice($user, 0,2);
You are getting the error because $users is a collection, not an array.
You could use the take method
$users = User::get()->take(3);
or the slice method
$users = User::get()->slice(3);
Here are some ways you can achieve this.
Applying the offset and limit directly to the query builder allows you to fetch only the needed rows.
$users = User::skip(5)->take(10)->get();
$users = User::offset(5)->limit(10)->get();
If you insist on working with complete result, then this approach is what to you need. You need to use collection slice method not array_slice since the result is a collection.
$users = User::all();
// Collection slice(offset, limit)
$users = $users->slice(5, 10);

Extract all possible values of AR column in yii2

Several models in yii2 are bound to a database using ActiveRecords. I now want to have a list of all ids of this model. Say, all user IDs when the Model is called User.
Sure I could just fetch all models and iterate over them, much like
$ids = [];
$users = User::find()->all();
foreach ($users as $user) {
$ids[] = $user->id;
}
But I feel there should be an easier way... Thanks in advance.
If you want to stay in ActiveRecord then this accomplishes the same thing:
$ids = User::find()->select('id')->column();
This returns array:
$ids = (new \yii\db\Query)->select('id')->from(User::tableName())->all();

(Laravel) only retrieving users that have a relationship

In my site I have users and items. Users can create items. I want to get an array that has all users, where the users which have an item go first and the users which do not have an item go after.
So far I have done this:
$users = User::all();
foreach($users as $user) {
if ($user->item) {
$sortedUsers + $user;
}
// now loop again and add users without relationship
This is pretty inefficient and I'm sure there's a much better way to do it.
You can query on the existence of a relationship
$users = User::has('items')->with('items')->get();
with that syntax you are telling laravel to fetch all users that have a item and to eager load the items;
Edit:
After reading it does not look like you actually want the items just the users that have a item in that case all you need is
$users = User::has('items')->get();
Without seeing the relation of Items to Users I'm not sure if this will work but you can try the following:
$users = Users::select('users.*')->orderBy('items.id')->with('items')->get();
Or it might work with just:
$users = Users::orderBy('items.id')->with('items')->get();
Update
$users = Users::orderBy('items.id')->join('items', 'items.user_id', '=', 'users.id')->get();
you can try
$users = User::with('item')->get();
foreach ($users as $user) {
echo $User->item->name;
}
You can use has() to get users with items and doesntHave() to get users without items:
$withItems = User::has('items')->get();
$withoutItems = User::doesntHave('items')->get();
And then merge() two collections:
$users = $withItems->merge($withoutItems);
You said you want an array, so you can convert result into an array with toArray()
$array = $users->toArray();

Eloquent column list by key with array as values?

So I can do this with Eloquent:
$roles = DB::table('roles')->lists('title', 'name');
But is there a way to make Eloquent fetch an array of values for each distinct key instead of just one column?
For instance, something like the following:
$roles = DB::table('roles')->lists(['*', DB:raw('COALESCE(value, default_value)')], 'name');
You can use the keyBy method:
$roles = Role::all()->keyBy('name');
If you're not using Eloquent, you can create a collection on your own:
$roles = collect(DB::table('roles')->get())->keyBy('name');
If you're using Laravel 5.3+, the query builder now actually returns a collection, so there's no need to manually wrap it in a collection again:
$roles = DB::table('roles')->get()->keyBy('name');
If you need a key/value array, since Laravel 5.1 you can use pluck. This way you can indicate which attributes you want to use as a value and as a key.
$plucked = MyModel::all()->pluck(
'MyNameAttribute',
'MyIDAttribute'
);
return $plucked->all();
You will get an array as follow:
array:3 [▼
1 => "My MyNameAttribute value"
2 => "Lalalala"
3 => "Oh!"
]
You may try something like this:
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item->id] = (Array)$item; // object to array
}, DB::table('roles')->get());
If you want to get an Object instead of an Array as value then just remove the (Array).
Alternative: Using Eloquent model (Instead of DB::table):
$roles = array();
array_map(function($item) use (&$roles) {
$roles[$item['id']] = $item;
}, Role::all()->toArray());
Another Alternative: Using Collection::map() method:
$roles = array();
Role::all()->map(function($item) use(&$roles) {
$roles[$item->id] = $item->toArray();
});

Categories