Laravel 컬렉션에서 특정 속성 만 가져옵니다.
Laravel Collections에 대한 문서와 API를 검토했지만 원하는 것을 찾지 못하는 것 같습니다.
컬렉션에서 모델 데이터가있는 배열을 검색하고 싶지만 지정된 속성 만 가져옵니다.
즉 Users::toArray('id','name','email')
, 컬렉션은 다른 곳에서 사용되기 때문에 실제로 사용자에 대한 모든 속성을 보유하지만이 특정 장소에서는 사용자 데이터와 지정된 속성 만있는 배열이 필요합니다.
라 라벨에 이것에 대한 도우미가없는 것 같습니까? -가장 쉬운 방법은 무엇입니까?
기존 Collection
방법 의 조합을 사용하여이를 수행 할 수 있습니다 . 처음에는 따라하기가 조금 어려울 수 있지만, 무너질만큼 쉬워야합니다.
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
return collect($user->toArray())
->only(['id', 'name', 'email'])
->all();
});
설명
첫째,이 map()
메서드는 기본적으로를 반복하고의 Collection
각 항목을 Collection
전달 된 콜백에 전달합니다. 콜백의 각 호출에서 반환 된 값 Collection
은 map()
메서드에 의해 생성 된 새 항목을 빌드합니다 .
collect($user->toArray())
속성 에서 새롭고 임시로 구축하는 Collection
것입니다 Users
.
->only(['id', 'name', 'email'])
Collection
지정된 속성 만 임시 로 줄 입니다.
->all()
임시 Collection
배열을 일반 배열로 되돌립니다.
모두 합치면 "사용자 컬렉션의 각 사용자에 대해 ID, 이름 및 이메일 속성의 배열 만 반환합니다."가 표시됩니다.
Laravel 5.5 업데이트
Laravel 5.5는 only
기본적으로와 동일한 작업을 수행 하는 메서드를 Model에 추가했습니다 collect($user->toArray())->only([...])->all()
. 따라서 5.5+ 에서는 다음과 같이 약간 단순화 할 수 있습니다.
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map(function ($user) {
return $user->only(['id', 'name', 'email']);
});
이것을 라 라벨 5.4에 도입 된 컬렉션에 대한 "고급 메시징" 과 결합하면 더욱 단순화 할 수 있습니다.
// get your main collection with all the attributes...
$users = Users::get();
// build your second collection with a subset of attributes. this new
// collection will be a collection of plain arrays, not Users models.
$subset = $users->map->only(['id', 'name', 'email']);
use User::get(['id', 'name', 'email'])
, 지정된 열이있는 컬렉션을 반환하고 배열로 만들려면 toArray()
다음 get()
과 같은 메서드 다음에 사용 하십시오 .
User::get(['id', 'name', 'email'])->toArray()
대부분의 경우 컬렉션은 실제로 스테로이드의 배열이고 컬렉션을 조작하는 데 사용하기 쉬운 메서드가 있기 때문에 컬렉션을 배열로 변환 할 필요가 없습니다.
나는 이제 이것에 대한 자체 해결책을 생각해 냈습니다.
1. 배열에서 특정 속성을 추출하는 일반 함수 생성
아래 함수는 연관 배열 또는 연관 배열의 배열에서 특정 속성 만 추출합니다 (마지막은 Laravel에서 $ collection-> toArray ()를 수행 할 때 얻는 것입니다).
It can be used like this:
$data = array_extract( $collection->toArray(), ['id','url'] );
I am using the following functions:
function array_is_assoc( $array )
{
return is_array( $array ) && array_diff_key( $array, array_keys(array_keys($array)) );
}
function array_extract( $array, $attributes )
{
$data = [];
if ( array_is_assoc( $array ) )
{
foreach ( $attributes as $attribute )
{
$data[ $attribute ] = $array[ $attribute ];
}
}
else
{
foreach ( $array as $key => $values )
{
$data[ $key ] = [];
foreach ( $attributes as $attribute )
{
$data[ $key ][ $attribute ] = $values[ $attribute ];
}
}
}
return $data;
}
This solution does not focus on performance implications on looping through the collections in large datasets.
2. Implement the above via a custom collection i Laravel
Since I would like to be able to simply do $collection->extract('id','url');
on any collection object, I have implemented a custom collection class.
First I created a general Model, which extends the Eloquent model, but uses a different collection class. All you models need to extend this custom model, and not the Eloquent Model then.
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model as EloquentModel;
use Lib\Collection;
class Model extends EloquentModel
{
public function newCollection(array $models = [])
{
return new Collection( $models );
}
}
?>
Secondly I created the following custom collection class:
<?php
namespace Lib;
use Illuminate\Support\Collection as EloquentCollection;
class Collection extends EloquentCollection
{
public function extract()
{
$attributes = func_get_args();
return array_extract( $this->toArray(), $attributes );
}
}
?>
Lastly, all models should then extend your custom model instead, like such:
<?php
namespace App\Models;
class Article extends Model
{
...
Now the functions from no. 1 above are neatly used by the collection to make the $collection->extract()
method available.
You need to define
$hidden
and$visible
attributes. They'll be set global (that means always return all attributes from$visible
array).Using method
makeVisible($attribute)
andmakeHidden($attribute)
you can dynamically change hidden and visible attributes. More: Eloquent: Serialization -> Temporarily Modifying Property Visibility
I had a similar issue where I needed to select values from a large array, but I wanted the resulting collection to only contain values of a single value.
pluck()
could be used for this purpose (if only 1 key item is required)
you could also use reduce()
. Something like this with reduce:
$result = $items->reduce(function($carry, $item) {
return $carry->push($item->getCode());
}, collect());
this is a follow up on the patricus [answer][1] above but for nested arrays:
$topLevelFields = ['id','status'];
$userFields = ['first_name','last_name','email','phone_number','op_city_id'];
return $onlineShoppers->map(function ($user) {
return collect($user)->only($topLevelFields)
->merge(collect($user['user'])->only($userFields))->all();
})->all();
this seems to work, but not sure if it's optimized for performance or not.
$request->user()->get(['id'])->groupBy('id')->keys()->all();
output:
array:2 [
0 => 4
1 => 1
]
$users = Users::get();
$subset = $users->map(function ($user) {
return array_only(user, ['id', 'name', 'email']);
});
ReferenceURL : https://stackoverflow.com/questions/38412091/get-only-specific-attributes-with-from-laravel-collection
'IT TIP' 카테고리의 다른 글
소스 트리를 사용하여 충돌이있는 rebase, 충돌이 해결 된 후 rebase가 작동하지 않음 (0) | 2021.01.10 |
---|---|
Android : CollapsingToolbarLayout 및 SwipeRefreshLayout이 중단됨 (0) | 2021.01.10 |
Typescript 인터페이스 내의 모든 속성을 선택 사항으로 설정 (0) | 2021.01.10 |
max-font-size를 구현하는 방법은 무엇입니까? (0) | 2021.01.10 |
UI 및 게임 오브젝트에서 클릭 / 터치 이벤트를 감지하는 방법 (0) | 2021.01.10 |