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()
대부분의 경우 컬렉션은 실제로 스테로이드의 배열이고 컬렉션을 조작하는 데 사용하기 쉬운 메서드가 있으므로 컬렉션을 배열로 변환 할 필요가 없습니다.
답변
아래 방법도 작동합니다.
$users = User::all()->map(function ($user) {
return collect($user)->only(['id', 'name', 'email']);
});
답변
나는 이제 이것에 대한 자체 해결책을 생각해 냈습니다.
1. 배열에서 특정 속성을 추출하는 일반 함수 생성
아래 함수는 연관 배열 또는 연관 배열의 배열에서 특정 속성 만 추출합니다 (마지막은 Laravel에서 $ collection-> toArray ()를 수행 할 때 얻는 것입니다).
다음과 같이 사용할 수 있습니다.
$data = array_extract( $collection->toArray(), ['id','url'] );
다음 기능을 사용하고 있습니다.
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;
}
이 솔루션은 대규모 데이터 세트의 컬렉션을 반복 할 때 성능에 미치는 영향에 초점을 맞추지 않습니다.
2. 사용자 지정 컬렉션을 통해 위의 구현 i Laravel
$collection->extract('id','url');
모든 컬렉션 개체에 대해 간단히 수행 할 수 있기를 원 하기 때문에 사용자 지정 컬렉션 클래스를 구현했습니다.
먼저 Eloquent 모델을 확장하지만 다른 컬렉션 클래스를 사용하는 일반 모델을 만들었습니다. 모든 모델은 Eloquent 모델이 아니라이 커스텀 모델을 확장해야합니다.
<?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 );
}
}
?>
둘째로 다음과 같은 사용자 지정 컬렉션 클래스를 만들었습니다.
<?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 );
}
}
?>
마지막으로, 모든 모델은 다음과 같이 대신 사용자 지정 모델을 확장해야합니다.
<?php
namespace App\Models;
class Article extends Model
{
...
이제 기능이 없습니다. 위의 1은 컬렉션에서 $collection->extract()
메서드를 사용할 수 있도록 깔끔하게 사용됩니다 .
답변
-
$hidden
및$visible
속성 을 정의해야 합니다. 전역으로 설정됩니다 (즉, 항상$visible
배열 에서 모든 속성을 반환 함 ). -
방법을 사용
makeVisible($attribute)
하고makeHidden($attribute)
동적 숨겨진 변경하고 눈에 보이는 속성. 추가 : Eloquent : 직렬화-> 일시적으로 속성 가시성 수정
답변
큰 배열에서 값을 선택해야하는 비슷한 문제가 있었지만 결과 컬렉션에 단일 값의 값만 포함되기를 원했습니다.
pluck()
이 용도로 사용할 수 있습니다 (단 하나의 키 항목 만 필요한 경우).
당신은 또한 사용할 수 있습니다 reduce()
. 다음과 같이 축소하십시오.
$result = $items->reduce(function($carry, $item) {
return $carry->push($item->getCode());
}, collect());
답변
이것은 위의 patricus [answer] [1]에 대한 후속 조치이지만 중첩 배열에 대한 것입니다.
$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();