web-dev-qa-db-fra.com

Laravel 4 - Obtenir un tableau d'attributs de la collection

J'ai une collection d'objets. Disons que les objets sont des balises:

$tags = Tag::all();

Je veux récupérer un certain attribut pour chaque balise, disons son nom. Bien sûr que je peux le faire

foreach ($tags as $tag) {
    $tag_names[] = $tag->name;
}

Mais existe-t-il une solution plus larvaire à ce problème?

Quelque chose comme $tags->name?

37
severin

Les collections ont une méthode lists similaire à la méthode des tableaux décrite par @Gadoma. Il renvoie un tableau contenant la valeur d'un attribut donné pour chaque élément de la collection.

Pour récupérer le tableau de noms souhaité de ma collection de balises, je peux simplement utiliser:

$tags->lists('name');

Mise à jour: À partir de laravel 5.2 lists est remplacé par pluck .

$tags->pluck('name');

Plus précisément, le guide de mise à niveau de laravel 5.2 indique que "[la] méthode lists sur les objets Collection, générateur de requêtes et générateur de requêtes Eloquent a été renommée pluck . La signature de la méthode reste la même. "

71
severin

Oui, vous pouvez le faire Nice et facilement. Comme le la documentation de Laravel 4 indique , vous pouvez faire

Récupération de toutes les lignes d'une table

$users = DB::table('users')->get();

foreach ($users as $user)
{
var_dump($user->name);
}

Récupération d'une seule ligne d'une table

$user = DB::table('users')->where('name', 'John')->first();

var_dump($user->name);

Récupération d'une seule colonne d'une ligne

$name = DB::table('users')->where('name', 'John')->pluck('name');

Récupération d'une liste de valeurs de colonne

$roles = DB::table('roles')->lists('title');

Cette méthode renvoie un tableau de titres de rôle. Vous pouvez également spécifier une colonne de clé personnalisée pour le tableau renvoyé:

$roles = DB::table('roles')->lists('title', 'name');

Spécification d'une clause de sélection

$users = DB::table('users')->select('name', 'email')->get();

$users = DB::table('users')->distinct()->get();

$users = DB::table('users')->select('name as user_name')->get();

MODIFIER:

Les exemples ci-dessus montrent comment accéder aux données à l'aide du générateur de requêtes fluide de Laravel. Si vous utilisez des modèles, vous pouvez accéder aux données avec Laravel's Eloquent ORM

Étant donné qu'Eloquent utilise en interne le générateur de requêtes, vous pouvez sans problème effectuer les opérations suivantes:

$tag_names = $tags->lists('tag_name_label', 'tag_name_column')->get();

ce qui pourrait également être fait avec:

$tag_names = DB::table('tags')->lists('tag_name_label', 'tag_name_column')->get();
26
Gadoma

Voici quelques extraits de ma propre expérimentation sur la question ce matin. Je souhaite seulement (et peut-être que quelqu'un d'autre connaît la solution) que la collection ait une méthode $ collection-> distinct (), afin que je puisse facilement générer une liste de valeurs de colonne basée sur une collection déjà filtrée.

Pensées?

J'espère que ces extraits aident à clarifier certaines options alternatives pour générer une liste de valeurs uniques à partir d'un tableau, d'une collection et d'un modèle éloquent.

tilisation d'une collection (heureux)

/**
 * Method A
 *     Store Collection to reduce queries when building multiple lists
 */
$people = Person::get();
$cities = array_unique( $people->lists('city') );
$states = array_unique( $people->lists('state') );
// etc...

tilisation d'un modèle éloquent (plus heureux)

/**
 * Method B
 *     Utilize the Eloquent model's methods
 *     One query per list
 */
// This will return an array of unique cities present in the list
$cities = Person::distinct()->lists('city');
$states = Person::distinct()->lists('state');

tilisation d'un modèle Eloquent PLUS Caching (le plus heureux)

/**
 * Method C
 *     Utilize the Eloquent model's methods PLUS the built in Caching
 *     Queries only run once expiry is reached
 */
$expiry = 60; // One Hour
$cities = Person::remember($expiry)->distinct()->lists('city');
$states = Person::remember($expiry)->distinct()->lists('state');

J'aimerais entendre des alternatives à cela si vous en avez un!

@ErikOnTheWeb

8
Erik Aybar

Vous pouvez utiliser array_column pour cela (c'est une fonction PHP 5.5 mais Laravel a une fonction d'assistance qui reproduit le comportement, pour la plupart)).

Quelque chose comme ça devrait suffire.

$tag_names = array_column($tags->toArray(), 'name');
4
Jason Lewis