get access to array build with pluck function in laravel - php

this is the query
$gg = DB::table('member_opinions')->where('user_id',$id)->pluck('committees_opinion');
result of dd($gg);
Illuminate\Support\Collection {#1436
#items: array:2 [
0 => "مؤهل"
1 => "غير مؤهل"
]
}
and I want to compare the values in loop in the controller

The each method iterates over the items in the collection and passes each item to a closure. Here you can compare the values.
$gg->each(function ($item, $key) {
//
});
More collections method is also present. Link for ref - https://laravel.com/docs/8.x/collections

Related

Set key to difference key when get laravel relationship

I want to change my collection array key to language code.
Here is my code
$products = Product::has('languages')->paginate(20);
return response()->json($products);
This is my relationship
public function languages($lang_id = null)
{
if ($lang_id)
return $this->hasMany(ProductLang::class)->where('lang_id', $lang_id)->first();
return $this->hasMany(ProductLang::class);
}
This is what I get for now.
Illuminate\Database\Eloquent\Collection {#613 ▼
#items: array:2 [▼
0 => App\Models\Product\ProductLang {#614 ▶}
1 => App\Models\Product\ProductLang {#615 ▶}
]
}
Expected:
Illuminate\Database\Eloquent\Collection {#613 ▼
#items: array:2 [▼
en => App\Models\Product\ProductLang {#614 ▶}
zh => App\Models\Product\ProductLang {#615 ▶}
]
}
Thanks for any help..
There is a collection method called keyBy. Also, I woudn't use a conditional parameter in a relationship the way you pass $lang_id. I'd rather create two relationship methods.
So, you can do:
$products = Product::has('languages')
->paginate(20)
->getCollection()
->map(function ($product) {
return $product->languages->keyBy('lang_id');
});
return response()->json($products);
You could try and remap the key of the loaded relationship after the query like so:
$products = Product::has('languages')->paginate(20);
foreach($products as $product){
$product->setRelation('languages', $product->languages->mapWithKeys(function($language){
// Assuming the code is in the attribute `language_code`
return [$language->language_code => $language];
}));
}
return response()->json($products);
You can use mapWithKeys collection method.
As per Laravel Documentation:
The mapWithKeys method iterates through the collection and passes each
value to the given callback. The callback should return an associative
array containing a single key / value pair:
$keyed = $products->mapWithKeys(function ($item) {
return [$item['locale'] => $item]; // assuming 'locale' key
});
$keyed->all();
References:
Laravel -> Collections -> Method mapwithkeys
Laracast -> Change eloquent model relationship key

How to build this Laravel Eloquent Query

I want to build a nested array from a simple table with Laravel Eloquent, but i couldn't.
So basically below is a snap shot of my table
and this is the array I want to build
You can use some methods from collection :
$result = $data->groupBy(['market_id', 'base_currency', 'currency_id'])
->map(function ($item) {
return $item->map(function ($item) {
return $item->map(function ($item) {
return $item->map(function ($item) {
return $item['currency_id'];
});
})->flatten();
})->sortKeys();
});
dd($result->toArray());
array:1 [
1 => array:2 [
1 => array:2 [
0 => 2
1 => 3
]
2 => array:2 [
0 => 1
1 => 2
]
]
]
Explanation
groupBy
The groupBy method groups the collection's items by a given key. Multiple grouping criteria may be passed as an array. Each array element will be applied to the corresponding level within a multi-dimensional array:
$data->groupBy(['market_id', 'base_currency', 'currency_id']);
map
The map method iterates through the collection and passes each value to the given callback.
->map(function ($item) {
return $item;
});
flatten
The flatten method flattens a multi-dimensional collection into a single dimension:
->flatten()
sortKeys
The sortKeys method sorts the collection by the keys of the underlying associative array:
->sortKeys()

search in values in array and get another value

I have an array like this:
//the result of `dd()` function in laravel
Collection {#401 ▼
#items: array:2 [▼
0 => {#400 ▼
+"tutorial_package_count": 2
+"tutorial_package_id": 1
+"tutorial_id": 1
}
1 => {#402 ▼
+"tutorial_package_count": 1
+"tutorial_package_id": 2
+"tutorial_id": 2
}
]
}
suppose I have a variable as $tutorial_id = 1,
now I want to get value of tutorial_package_count. at this here I want 2.
I dont want to use a loop.
In this case you can use filter method available for collections:
$filtered = $collection->filter(function ($value, $key) use($tutorial_id) {
return $value['tutorial_id'] == $tutorial_id;
});
$firstMatch = $filtered->first();

Add simple array to Collection

in laravel this method is return Collection type of result:
$all_currency = CurrencyType::lists('currency_type', 'id');
Result:
Collection {#687 ▼
#items: array:2 [▼
1 => "EUR"
2 => "CHF"
]
}
now and i want to add -1 => "USD" to that. but i cant do it. my solution create nested array into that. for example:
$all_currency->push (["-1"=>"11"]);
Result:
Collection {#687 ▼
#items: array:4 [▼
1 => "EUR"
2 => "CHF"
3 => array:1 [▼
-1 => "USD"
]
]
}
If you need to use array, you can try to convert collection to an array with toArray() method:
$all_currency = CurrencyType::pluck('currency_type', 'id')->toArray();
$all_currency['-1'] = '11';
If you need to use collection, use put() helper:
$all_currency = CurrencyType::pluck('currency_type', 'id')->put('-1', '11');
Also, lists() is deprecated and will be removed in future, use pluck() instead.
Did you try to cast the collection to array before adding the currency?
Otherwise, it might help to check out the interface of the Collection class. Since you didn't mention it, it could be Doctrine or Propel or something else?
You then might find out, that there is a special function for adding a key-value pair, since pushing a value, adds that value (an array in your case) to the collection which is not what you want.
There might be no way of adding a value to a specific key index -1, that all depends on which ORM you are actually using and it's implementation.
//edit:
It seems the correct method is put and the code should look like this:
$all_currency->push (-1, "11");
https://laravel.com/api/master/Illuminate/Support/Collection.html#method_put
Use the put() method on your collection:
$all_currency->put(-1, "USD");
You can see all available methods for collections here: Collections

Manually add item to existing object [Laravel 5]

Here is what I try to do:
$q = Question::where('id',$id -> id)->get();
$q[] = $q->push([ 'test' => true]);
dd($q);
This will output:
Collection {#220 ▼
#items: array:3 [▼
0 => Question {#225 ▶}
1 => array:1 [▼
"test" => true
]
2 => null
]
}
So 'test' => true will append as a new key, but I want to insert it in Question so latter I can access to it like this with foreach $q -> test
So here is how I want access to item:
#foreach($q as $qq)
{{ $qq->test }}
#endforeach
It can be done by using setAttribute() function of Eloquent Model (https://github.com/illuminate/database/blob/master/Eloquent/Model.php).
As You can see it stores data in protected $attributes using setAttribute(), and when we do $SomeModel->some_field it uses magic method __get() to retrieve item by association from attributes array.
Here is the resolution to Your question:
$Question = Question::find($id);
$Question->setAttribute('test', 'blablabla');
Apart from setAttribute(), you can use put() refer to this post for one item. And map() for many items, refer to this post.

Categories