Collezioni

Introduzione

La classe Illuminate\Support\Collection offre un wrapper fluido e comodo per lavorare con array di dati. Ad esempio, dai un’occhiata al seguente codice. Useremo l’helper collect per creare una nuova istanza di collection dall’array, applicare la funzione strtoupper a ogni elemento e poi rimuovere tutti gli elementi vuoti:

$collection = collect(['taylor', 'abigail', null])->map(function (?string $name) {
    return strtoupper($name);
})->reject(function (string $name) {
    return empty($name);
});

Come puoi vedere, la classe Collection ti permette di concatenare i suoi metodi per eseguire mappe e riduzioni in modo fluido sull’array sottostante. In generale, le collection sono immutabili, il che significa che ogni metodo di Collection restituisce una nuova istanza di Collection.

Creare Collezioni

Come detto sopra, l’helper collect restituisce una nuova istanza di Illuminate\Support\Collection per l’array fornito. Quindi, creare una collezione è semplice come:

    $collection = collect([1, 2, 3]);

I risultati delle query Eloquent vengono sempre restituiti come istanze di Collection.

Estendere le Collezioni

Le Collezioni sono "macroable", il che permette di aggiungere metodi aggiuntivi alla classe Collection durante l’esecuzione. Il metodo macro della classe Illuminate\Support\Collection accetta una closure che verrà eseguita quando il tuo macro viene chiamato. La closure del macro può accedere agli altri metodi della collezione tramite $this, proprio come se fosse un vero metodo della classe collezione. Ad esempio, il seguente codice aggiunge un metodo toUpper alla classe Collection:

use Illuminate\Support\Collection;
use Illuminate\Support\Str;

Collection::macro('toUpper', function () {
    return $this->map(function (string $value) {
        return Str::upper($value);
    });
});

$collection = collect(['first', 'second']);

$upper = $collection->toUpper();

// ['FIRST', 'SECOND']

Di solito, dovresti dichiarare i macro delle collezioni nel metodo boot di un service provider.

Argomenti delle Macro

Se necessario, puoi definire macro che accettano argomenti aggiuntivi:

use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Lang;

Collection::macro('toLocale', function (string $locale) {
    return $this->map(function (string $value) use ($locale) {
        return Lang::get($value, [], $locale);
    });
});

$collection = collect(['first', 'second']);

$translated = $collection->toLocale('es');

Metodi Disponibili

Per la maggior parte della documentazione rimanente sulle collezioni, discuteremo ogni metodo disponibile nella classe Collection. Ricorda, tutti questi metodi possono essere concatenati per manipolare facilmente l’array sottostante. Inoltre, quasi ogni metodo restituisce una nuova istanza di Collection, permettendoti di mantenere la copia originale della collezione quando necessario:

Elenco dei Metodi

after()

Il metodo after restituisce l’elemento successivo a quello specificato. Viene restituito null se l’elemento non viene trovato o se è l’ultimo elemento:

$collection = collect([1, 2, 3, 4, 5]);

$collection->after(3);

// 4

$collection->after(5);

// null

Questo metodo cerca l’elemento dato usando un confronto "loose", il che significa che una stringa contenente un valore intero verrà considerata uguale a un intero dello stesso valore. Per usare un confronto "rigoroso", puoi fornire l’argomento strict al metodo:

collect([2, 4, 6, 8])->after('4', strict: true);

// null

In alternativa, puoi fornire una tua closure per cercare il primo elemento che supera un determinato test di verità:

collect([2, 4, 6, 8])->after(function (int $item, int $key) {
    return $item > 5;
});

// 8

all()

Il metodo all restituisce l’array sottostante rappresentato dalla collezione:

    collect([1, 2, 3])->all();
    
    // [1, 2, 3]

average()

Alias del metodo avg.

avg()

Il metodo avg restituisce il valore medio di una determinata chiave:

$average = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->avg('foo');

// 20

$average = collect([1, 1, 2, 4])->avg();

// 2

before()

Il metodo before è l’opposto del metodo after. Restituisce l’elemento che precede l’elemento specificato. Se l’elemento dato non viene trovato o è il primo elemento, restituisce null:

$collection = collect([1, 2, 3, 4, 5]);

$collection->before(3);

// 2

$collection->before(1);

// null

collect([2, 4, 6, 8])->before('4', strict: true);

// null

collect([2, 4, 6, 8])->before(function (int $item, int $key) {
    return $item > 5;
});

// 4

chunk()

Il metodo chunk suddivide la collezione in più collezioni più piccole di una dimensione specificata:

    $collection = collect([1, 2, 3, 4, 5, 6, 7]);

    $chunks = $collection->chunk(4);

    $chunks->all();

    // [[1, 2, 3, 4], [5, 6, 7]]

Questo metodo è particolarmente utile nelle views quando si lavora con un sistema a griglia come Bootstrap. Ad esempio, immagina di avere una collezione di modelli Eloquent che vuoi mostrare in una griglia:

@foreach ($products->chunk(3) as $chunk)
    <div class="row">
        @foreach ($chunk as $product)
            <div class="col-xs-4">{{ $product->name }}</div>
        @endforeach
    </div>
@endforeach

chunkWhile()

Il metodo chunkWhile divide la collezione in più collezioni più piccole basandosi sulla valutazione della callback fornita. La variabile $chunk passata alla closure può essere utilizzata per ispezionare l’elemento precedente:

$collection = collect(str_split('AABBCCCD'));

$chunks = $collection->chunkWhile(function (string $value, int $key, Collection $chunk) {
    return $value === $chunk->last();
});

$chunks->all();

// [['A', 'A'], ['B', 'B'], ['C', 'C', 'C'], ['D']]

collapse()

Il metodo collapse unisce una collezione di array in una singola collezione piatta:

$collection = collect([
    [1, 2, 3],
    [4, 5, 6],
    [7, 8, 9],
]);

$collapsed = $collection->collapse();

$collapsed->all();

// [1, 2, 3, 4, 5, 6, 7, 8, 9]

collect()

Il metodo collect restituisce una nuova istanza di Collection con gli elementi attualmente presenti nella collezione:

    $collectionA = collect([1, 2, 3]);

    $collectionB = $collectionA->collect();

    $collectionB->all();

    // [1, 2, 3]

Il metodo collect è principalmente utile per convertire lazy collections in istanze standard di Collection:

    $lazyCollection = LazyCollection::make(function () {
        yield 1;
        yield 2;
        yield 3;
    });

    $collection = $lazyCollection->collect();

    $collection::class;

    // 'Illuminate\Support\Collection'

    $collection->all();

    // [1, 2, 3]

Il metodo collect è particolarmente utile quando hai un’istanza di Enumerable e hai bisogno di un’istanza di collezione non lazy. Poiché collect() fa parte del contratto Enumerable, puoi usarlo in sicurezza per ottenere un’istanza di Collection.

combine()

Il metodo combine unisce i valori della collection, come chiavi, con i valori di un altro array o collection:

$collection = collect(['name', 'age']);

$combined = $collection->combine(['George', 29]);

$combined->all();

// ['name' => 'George', 'age' => 29]

concat()

Il metodo concat aggiunge i valori dell’array o della collection fornita alla fine di un’altra collection:

    $collection = collect(['John Doe']);

    $concatenated = $collection->concat(['Jane Doe'])->concat(['name' => 'Johnny Doe']);

    $concatenated->all();

    // ['John Doe', 'Jane Doe', 'Johnny Doe']

Il metodo concat riassegna numericamente le chiavi degli elementi concatenati alla collection originale. Per mantenere le chiavi nelle collection associative, vedi il metodo merge method.

contains()

Il metodo contains determina se la collezione contiene un elemento specificato. Puoi passare una closure al metodo contains per verificare se esiste un elemento nella collezione che soddisfa un determinato criterio:

$collection = collect([1, 2, 3, 4, 5]);

$collection->contains(function (int $value, int $key) {
    return $value > 5;
});

// false

In alternativa, puoi passare una stringa al metodo contains per verificare se la collezione contiene un determinato valore:

$collection = collect(['name' => 'Desk', 'price' => 100]);

$collection->contains('Desk');

// true

$collection->contains('New York');

// false

Puoi anche passare una coppia chiave/valore al metodo contains, che verificherà se la coppia fornita esiste nella collezione:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
]);

$collection->contains('product', 'Bookcase');

// false

Il metodo contains utilizza confronti "non stretti" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero con lo stesso valore. Usa il metodo containsStrict per filtrare usando confronti "stretti".

Per l’inverso di contains, vedi il metodo doesntContain.

containsOneItem()

Il metodo containsOneItem controlla se la collezione contiene un solo elemento:

collect([])->containsOneItem();

// false

collect(['1'])->containsOneItem();

// true

collect(['1', '2'])->containsOneItem();

// false

containsStrict()

Questo metodo ha la stessa firma del metodo contains; tuttavia, tutti i valori vengono confrontati usando confronti "stretti".

Il comportamento di questo metodo viene modificato quando si utilizzano le Eloquent Collections.

count()

Il metodo count restituisce il numero totale di elementi nella collezione:

    $collection = collect([1, 2, 3, 4]);

    $collection->count();

    // 4

countBy()

Il metodo countBy conta le occorrenze dei valori nella collezione. Per impostazione predefinita, il metodo conta le occorrenze di ogni elemento, permettendoti di contare determinati "tipi" di elementi nella collezione:

$collection = collect([1, 2, 2, 2, 3]);

$counted = $collection->countBy();

$counted->all();

// [1 => 1, 2 => 3, 3 => 1]

Passi una closure al metodo countBy per contare tutti gli elementi per un valore personalizzato:

$collection = collect(['alice@gmail.com', 'bob@yahoo.com', 'carlos@gmail.com']);

$counted = $collection->countBy(function (string $email) {
    return substr(strrchr($email, "@"), 1);
});

$counted->all();

// ['gmail.com' => 2, 'yahoo.com' => 1]

crossJoin()

Il metodo crossJoin combina i valori della collezione con gli array o le collezioni fornite, restituendo un prodotto cartesiano con tutte le permutazioni possibili:

$collection = collect([1, 2]);

$matrix = $collection->crossJoin(['a', 'b']);

$matrix->all();

/*
    [
        [1, 'a'],
        [1, 'b'],
        [2, 'a'],
        [2, 'b'],
    ]
*/
$collection = collect([1, 2]);

$matrix = $collection->crossJoin(['a', 'b'], ['I', 'II']);

$matrix->all();

/*
    [
        [1, 'a', 'I'],
        [1, 'a', 'II'],
        [1, 'b', 'I'],
        [1, 'b', 'II'],
        [2, 'a', 'I'],
        [2, 'a', 'II'],
        [2, 'b', 'I'],
        [2, 'b', 'II'],
    ]
*/

dd()

Il metodo dd mostra gli elementi della collection e termina l’esecuzione dello script:

$collection = collect(['John Doe', 'Jane Doe']);

$collection->dd();

/*
	Collection {
	#items: array:2 [
					0 => "John Doe"
					1 => "Jane Doe"
			]
	}
*/

Se non desideri interrompere l’esecuzione dello script, utilizza invece il metodo dump.

diff()

Il metodo diff confronta la collection con un’altra collection o con un semplice array PHP basandosi sui suoi valori. Questo metodo restituirà i valori nella collection originale che non sono presenti nella collection fornita:

    $collection = collect([1, 2, 3, 4, 5]);

    $diff = $collection->diff([2, 4, 6, 8]);

    $diff->all();

    // [1, 3, 5]

Il comportamento di questo metodo viene modificato quando si utilizzano Eloquent Collections.

diffAssoc()

Il metodo diffAssoc confronta la collection con un’altra collection o un semplice array PHP in base alle sue chiavi e ai suoi valori. Questo metodo restituirà le coppie chiave/valore nella collection originale che non sono presenti nella collection fornita:

$collection = collect([
    'color' => 'orange',
    'type' => 'fruit',
    'remain' => 6,
]);

$diff = $collection->diffAssoc([
    'color' => 'yellow',
    'type' => 'fruit',
    'remain' => 3,
    'used' => 6,
]);

$diff->all();

// ['color' => 'orange', 'remain' => 6]

diffAssocUsing()

A differenza di diffAssoc, diffAssocUsing accetta una funzione callback fornita dall’utente per il confronto degli indici:

$collection = collect([
    'color' => 'orange',
    'type' => 'fruit',
    'remain' => 6,
]);

$diff = $collection->diffAssocUsing([
    'Color' => 'yellow',
    'Type' => 'fruit',
    'Remain' => 3,
], 'strnatcasecmp');

$diff->all();

// ['color' => 'orange', 'remain' => 6]

La callback deve essere una funzione di confronto che restituisce un intero minore, uguale o maggiore di zero. Per maggiori informazioni, consulta la documentazione PHP su array_diff_uassoc, che è la funzione PHP utilizzata internamente dal metodo diffAssocUsing.

diffKeys()

Il metodo diffKeys confronta la collezione con un’altra collezione o con un semplice array PHP basandosi sulle chiavi. Questo metodo restituirà le coppie chiave/valore nella collezione originale che non sono presenti nella collezione fornita:

$collection = collect([
    'one' => 10,
    'two' => 20,
    'three' => 30,
    'four' => 40,
    'five' => 50,
]);

$diff = $collection->diffKeys([
    'two' => 2,
    'four' => 4,
    'six' => 6,
    'eight' => 8,
]);

$diff->all();

// ['one' => 10, 'three' => 30, 'five' => 50]

doesntContain()

Il metodo doesntContain determina se la collezione non contiene un elemento specificato. Puoi passare una closure al metodo doesntContain per verificare se un elemento che soddisfa una determinata condizione non esiste nella collezione:

    $collection = collect([1, 2, 3, 4, 5]);

    $collection->doesntContain(function (int $value, int $key) {
        return $value < 5;
    });

    // false

In alternativa, puoi passare una stringa al metodo doesntContain per verificare se la collezione non contiene un determinato valore:

    $collection = collect(['name' => 'Desk', 'price' => 100]);

    $collection->doesntContain('Table');

    // true

    $collection->doesntContain('Desk');

    // false

Puoi anche passare una coppia chiave/valore al metodo doesntContain, che verificherà se la coppia specificata non esiste nella collezione:

    $collection = collect([
        ['product' => 'Desk', 'price' => 200],
        ['product' => 'Chair', 'price' => 100],
    ]);

    $collection->doesntContain('product', 'Bookcase');

    // true

Il metodo doesntContain utilizza confronti "flessibili" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero con lo stesso valore.

dot()

Il metodo dot appiattisce una collezione multidimensionale in una collezione a un solo livello che utilizza la notazione "dot" per indicare la profondità:

    $collection = collect(['products' => ['desk' => ['price' => 100]]]);

    $flattened = $collection->dot();

    $flattened->all();

    // ['products.desk.price' => 100]

dump()

Il metodo dump mostra gli elementi della collection:

    $collection = collect(['John Doe', 'Jane Doe']);

    $collection->dump();

    /*
        Collection {
					#items: array:2 [
									0 => "John Doe"
									1 => "Jane Doe"
							]
					}
			*/

duplicates()

Il metodo duplicates recupera e restituisce i valori duplicati dalla collection:

    $collection = collect(['a', 'b', 'a', 'c', 'b']);

    $collection->duplicates();

    // [2 => 'a', 4 => 'b']

Se la collection contiene array o oggetti, puoi passare la chiave degli attributi che desideri verificare per i valori duplicati:

    $employees = collect([
        ['email' => 'abigail@example.com', 'position' => 'Developer'],
        ['email' => 'james@example.com', 'position' => 'Designer'],
        ['email' => 'victoria@example.com', 'position' => 'Developer'],
    ]);

    $employees->duplicates('position');

    // [2 => 'Developer']

duplicatesStrict()

Questo metodo ha la stessa firma del metodo duplicates; tuttavia, tutti i valori vengono confrontati usando confronti "stretti".

each()

Il metodo each itera sugli elementi della collection e passa ogni elemento a una closure:

$collection = collect([1, 2, 3, 4]);

$collection->each(function (int $item, int $key) {
    // ...
});

Se vuoi interrompere l’iterazione attraverso gli elementi, puoi restituire false dalla tua closure:

$collection->each(function (int $item, int $key) {
    if (/* condizione */) {
        return false;
    }
});

eachSpread()

Il metodo eachSpread itera sugli elementi della collezione, passando ogni valore degli elementi nidificati al callback fornito:

$collection = collect([['John Doe', 35], ['Jane Doe', 33]]);

$collection->eachSpread(function (string $name, int $age) {
    // ...
});

Puoi interrompere l’iterazione degli elementi ritornando false dal callback:

$collection->eachSpread(function (string $name, int $age) {
    return false;
});

ensure()

Il metodo ensure serve a verificare che tutti gli elementi di una collezione siano di un tipo specifico o di una lista di tipi. In caso contrario, verrà generata un’UnexpectedValueException:

    return $collection->ensure(User::class);

    return $collection->ensure([User::class, Customer::class]);

Possono essere specificati anche tipi primitivi come string, int, float, bool e array:

    return $collection->ensure('int');

Il metodo ensure non garantisce che elementi di tipi diversi non vengano aggiunti alla collezione in seguito.

every()

Il metodo every può essere utilizzato per verificare che tutti gli elementi di una collection soddisfino un determinato test:

collect([1, 2, 3, 4])->every(function (int $value, int $key) {
    return $value > 2;
});

// false

Se la collection è vuota, il metodo every restituirà true:

$collection = collect([]);

$collection->every(function (int $value, int $key) {
    return $value > 2;
});

// true

except()

Il metodo except restituisce tutti gli elementi nella collection tranne quelli con le chiavi specificate:

    $collection = collect(['product_id' => 1, 'price' => 100, 'discount' => false]);

    $filtered = $collection->except(['price', 'discount']);

    $filtered->all();

    // ['product_id' => 1]

Per l’inverso di except, vedi il metodo only.

Il comportamento di questo metodo viene modificato quando si usano le Eloquent Collections.

filter()

Il metodo filter filtra la collection utilizzando il callback fornito, mantenendo solo gli elementi che superano un determinato test di verità:

$collection = collect([1, 2, 3, 4]);

$filtered = $collection->filter(function (int $value, int $key) {
    return $value > 2;
});

$filtered->all();

// [3, 4]

Se non viene fornito alcun callback, tutte le voci della collection equivalenti a false verranno rimosse:

$collection = collect([1, 2, 3, null, false, '', 0, []]);

$collection->filter()->all();

// [1, 2, 3]

Per l’inverso di filter, consulta il metodo reject.

first()

Il metodo first restituisce il primo elemento nella collection che supera un determinato test:

collect([1, 2, 3, 4])->first(function (int $value, int $key) {
    return $value > 2;
});

// 3

Puoi anche chiamare il metodo first senza argomenti per ottenere il primo elemento nella collection. Se la collection è vuota, viene restituito null:

collect([1, 2, 3, 4])->first();

// 1

firstOrFail()

Il metodo firstOrFail è identico al metodo first; tuttavia, se non viene trovato alcun risultato, verrà lanciata un’eccezione Illuminate\Support\ItemNotFoundException:

collect([1, 2, 3, 4])->firstOrFail(function (int $value, int $key) {
    return $value > 5;
});

// Lancia ItemNotFoundException...

Puoi anche chiamare il metodo firstOrFail senza argomenti per ottenere il primo elemento della collezione. Se la collezione è vuota, verrà lanciata un’eccezione Illuminate\Support\ItemNotFoundException:

collect([])->firstOrFail();

// Lancia ItemNotFoundException...

firstWhere()

Il metodo firstWhere restituisce il primo elemento nella collezione con la coppia chiave / valore data:

    $collection = collect([
        ['name' => 'Regena', 'age' => null],
        ['name' => 'Linda', 'age' => 14],
        ['name' => 'Diego', 'age' => 23],
        ['name' => 'Linda', 'age' => 84],
    ]);

    $collection->firstWhere('name', 'Linda');

    // ['name' => 'Linda', 'age' => 14]

Puoi anche chiamare il metodo firstWhere con un operatore di confronto:

    $collection->firstWhere('age', '>=', 18);

    // ['name' => 'Diego', 'age' => 23]

Come il metodo where, puoi passare un argomento al metodo firstWhere. In questo scenario, il metodo firstWhere restituirà il primo elemento dove il valore della chiave data è "truthy":

    $collection->firstWhere('age');

    // ['name' => 'Linda', 'age' => 14]

flatMap()

Il metodo flatMap itera attraverso la collezione e passa ogni valore alla closure fornita. La closure può modificare l’elemento e restituirlo, formando così una nuova collezione di elementi modificati. Successivamente, l’array viene appiattito di un livello:

$collection = collect([
    ['name' => 'Sally'],
    ['school' => 'Arkansas'],
    ['age' => 28]
]);

$flattened = $collection->flatMap(function (array $values) {
    return array_map('strtoupper', $values);
});

$flattened->all();

// ['name' => 'SALLY', 'school' => 'ARKANSAS', 'age' => '28'];

flatten()

Il metodo flatten appiattisce una collezione multidimensionale in una singola dimensione:

$collection = collect([
    'name' => 'taylor',
    'languages' => [
        'php', 'javascript'
    ]
]);

$flattened = $collection->flatten();

$flattened->all();

// ['taylor', 'php', 'javascript'];

Se necessario, puoi passare al metodo flatten un argomento di "profondità":

$collection = collect([
    'Apple' => [
        [
            'name' => 'iPhone 6S',
            'brand' => 'Apple'
        ],
    ],
    'Samsung' => [
        [
            'name' => 'Galaxy S7',
            'brand' => 'Samsung'
        ],
    ],
]);

$products = $collection->flatten(1);

$products->values()->all();

/*
    [
        ['name' => 'iPhone 6S', 'brand' => 'Apple'],
        ['name' => 'Galaxy S7', 'brand' => 'Samsung'],
    ]
*/

In questo esempio, chiamare flatten senza specificare la profondità avrebbe appiattito anche gli array annidati, risultando in ['iPhone 6S', 'Apple', 'Galaxy S7', 'Samsung']. Fornire una profondità permette di specificare il numero di livelli degli array annidati che verranno appiattiti.

flip()

Il metodo flip scambia le chiavi della collezione con i loro valori corrispondenti:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$flipped = $collection->flip();

$flipped->all();

// ['taylor' => 'name', 'laravel' => 'framework']

forget()

Il metodo forget rimuove un elemento dalla collezione in base alla sua chiave:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

// Rimuovi una singola chiave...
$collection->forget('name');

// ['framework' => 'laravel']

// Rimuovi più chiavi...
$collection->forget(['name', 'framework']);

// []

A differenza della maggior parte degli altri metodi delle collezioni, forget non restituisce una nuova collezione modificata; modifica e restituisce la collezione originale.

forPage()

Il metodo forPage restituisce una nuova collezione contenente gli elementi che sarebbero presenti su un determinato numero di pagina. Il metodo accetta il numero di pagina come primo argomento e il numero di elementi da mostrare per pagina come secondo argomento:

$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9]);

$chunk = $collection->forPage(2, 3);

$chunk->all();

// [4, 5, 6]

get()

Il metodo get restituisce l’elemento associato a una chiave specifica. Se la chiave non esiste, viene restituito null:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('name');

// taylor

Puoi opzionalmente passare un valore di default come secondo argomento:

$collection = collect(['name' => 'taylor', 'framework' => 'laravel']);

$value = $collection->get('age', 34);

// 34

Puoi anche passare una callback come valore di default. Il risultato della callback verrà restituito se la chiave specificata non esiste:

$collection->get('email', function () {
    return 'taylor@example.com';
});

// taylor@example.com

groupBy()

Il metodo groupBy raggruppa gli elementi della collection in base a una chiave specifica:

$collection = collect([
    ['account_id' => 'account-x10', 'product' => 'Chair'],
    ['account_id' => 'account-x10', 'product' => 'Bookcase'],
    ['account_id' => 'account-x11', 'product' => 'Desk'],
]);

$grouped = $collection->groupBy('account_id');

$grouped->all();

/*
    [
        'account-x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'account-x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

Invece di passare una stringa key, puoi passare una callback. La callback deve restituire il valore con cui vuoi raggruppare:

$grouped = $collection->groupBy(function (array $item, int $key) {
    return substr($item['account_id'], -3);
});

$grouped->all();

/*
    [
        'x10' => [
            ['account_id' => 'account-x10', 'product' => 'Chair'],
            ['account_id' => 'account-x10', 'product' => 'Bookcase'],
        ],
        'x11' => [
            ['account_id' => 'account-x11', 'product' => 'Desk'],
        ],
    ]
*/

Possono essere passati più criteri di raggruppamento come un array. Ogni elemento dell’array verrà applicato al livello corrispondente all’interno di un array multidimensionale:

$data = new Collection([
    10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
    20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
    30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
    40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
]);

$result = $data->groupBy(['skill', function (array $item) {
    return $item['roles'];
}], preserveKeys: true);

/*
[
    1 => [
        'Role_1' => [
            10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
            20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
        ],
        'Role_2' => [
            20 => ['user' => 2, 'skill' => 1, 'roles' => ['Role_1', 'Role_2']],
        ],
        'Role_3' => [
            10 => ['user' => 1, 'skill' => 1, 'roles' => ['Role_1', 'Role_3']],
        ],
    ],
    2 => [
        'Role_1' => [
            30 => ['user' => 3, 'skill' => 2, 'roles' => ['Role_1']],
        ],
        'Role_2' => [
            40 => ['user' => 4, 'skill' => 2, 'roles' => ['Role_2']],
        ],
    ],
];
*/

has()

Il metodo has verifica se una chiave specifica esiste nella collezione:

    $collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);

    $collection->has('product');

    // true

    $collection->has(['product', 'amount']);

    // true

    $collection->has(['amount', 'price']);

    // false

hasAny()

Il metodo hasAny verifica se almeno una delle chiavi fornite esiste nella collezione:

$collection = collect(['account_id' => 1, 'product' => 'Desk', 'amount' => 5]);

$collection->hasAny(['product', 'price']);

// true

$collection->hasAny(['name', 'price']);

// false

implode()

Il metodo implode unisce gli elementi in una collection. I suoi argomenti dipendono dal tipo di elementi nella collection. Se la collection contiene array o oggetti, devi passare la chiave degli attributi che vuoi unire e la stringa di "colla" da inserire tra i valori:

    $collection = collect([
        ['account_id' => 1, 'product' => 'Desk'],
        ['account_id' => 2, 'product' => 'Chair'],
    ]);

    $collection->implode('product', ', ');

    // Desk, Chair

Se la collection contiene semplici stringhe o valori numerici, devi passare la "colla" come unico argomento al metodo:

    collect([1, 2, 3, 4, 5])->implode('-');

    // '1-2-3-4-5'

Puoi passare una closure al metodo implode se vuoi formattare i valori da unire:

    $collection->implode(function (array $item, int $key) {
        return strtoupper($item['product']);
    }, ', ');

    // DESK, CHAIR

intersect()

Il metodo intersect rimuove i valori dalla collezione originale che non sono presenti nell’array o nella collezione fornita. La collezione risultante manterrà le chiavi originali della collezione:

$collection = collect(['Desk', 'Sofa', 'Chair']);

$intersect = $collection->intersect(['Desk', 'Chair', 'Bookcase']);

$intersect->all();

// [0 => 'Desk', 2 => 'Chair']

Il comportamento di questo metodo viene modificato quando si utilizzano le Eloquent Collections.

intersectAssoc()

Il metodo intersectAssoc confronta la collezione originale con un’altra collezione o con un array, restituendo le coppie chiave/valore presenti in tutte le collezioni fornite:

$collection = collect([
    'color' => 'red',
    'size' => 'M',
    'material' => 'cotton'
]);

$intersect = $collection->intersectAssoc([
    'color' => 'blue',
    'size' => 'M',
    'material' => 'polyester'
]);

$intersect->all();

// ['size' => 'M']

intersectByKeys()

Il metodo intersectByKeys rimuove tutte le chiavi e i loro valori corrispondenti dalla collezione originale che non sono presenti nell’array o nella collezione fornita:

$collection = collect([
    'serial' => 'UX301', 'type' => 'screen', 'year' => 2009,
]);

$intersect = $collection->intersectByKeys([
    'reference' => 'UX404', 'type' => 'tab', 'year' => 2011,
]);

$intersect->all();

// ['type' => 'screen', 'year' => 2009]

isEmpty()

Il metodo isEmpty restituisce true se la collezione è vuota; altrimenti, restituisce false:

collect([])->isEmpty();

// true

isNotEmpty()

Il metodo isNotEmpty restituisce true se la collezione non è vuota; altrimenti, restituisce false:

    collect([])->isNotEmpty();

    // false

join()

Il metodo join unisce i valori della collezione con una stringa. Usando il secondo argomento di questo metodo, puoi anche specificare come l’ultimo elemento deve essere aggiunto alla stringa:

collect(['a', 'b', 'c'])->join(', '); // 'a, b, c'
collect(['a', 'b', 'c'])->join(', ', ', and '); // 'a, b, and c'
collect(['a', 'b'])->join(', ', ' and '); // 'a and b'
collect(['a'])->join(', ', ' and '); // 'a'
collect([])->join(', ', ' and '); // ''

keyBy()

Il metodo keyBy assegna le chiavi alla collezione in base alla chiave fornita. Se più elementi hanno la stessa chiave, solo l’ultimo verrà mostrato nella nuova collezione:

    $collection = collect([
        ['product_id' => 'prod-100', 'name' => 'Desk'],
        ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]);

    $keyed = $collection->keyBy('product_id');

    $keyed->all();

    /*
        [
            'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
            'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
        ]
    */

Puoi anche passare una callback al metodo. La callback deve restituire il valore con cui assegnare la chiave alla collezione:

    $keyed = $collection->keyBy(function (array $item, int $key) {
        return strtoupper($item['product_id']);
    });

    $keyed->all();

    /*
        [
            'PROD-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
            'PROD-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
        ]
    */

keys()

Il metodo keys restituisce tutte le chiavi della collezione:

$collection = collect([
    'prod-100' => ['product_id' => 'prod-100', 'name' => 'Desk'],
    'prod-200' => ['product_id' => 'prod-200', 'name' => 'Chair'],
]);

$keys = $collection->keys();

$keys->all();

// ['prod-100', 'prod-200']

last()

Il metodo last restituisce l’ultimo elemento nella collezione che soddisfa una determinata condizione:

collect([1, 2, 3, 4])->last(function (int $value, int $key) {
    return $value < 3;
});

// 2

Puoi anche chiamare il metodo last senza argomenti per ottenere l’ultimo elemento della collezione. Se la collezione è vuota, viene restituito null:

collect([1, 2, 3, 4])->last();

// 4

lazy()

Il metodo lazy restituisce una nuova istanza di LazyCollection dall’array sottostante di elementi:

$lazyCollection = collect([1, 2, 3, 4])->lazy();

$lazyCollection::class;

// Illuminate\Support\LazyCollection

$lazyCollection->all();

// [1, 2, 3, 4]

Questo è particolarmente utile quando hai bisogno di eseguire trasformazioni su una Collection enorme che contiene molti elementi:

$count = $hugeCollection
    ->lazy()
    ->where('country', 'FR')
    ->where('balance', '>', '100')
    ->count();

Convertendo la collection in una LazyCollection, evitiamo di dover allocare una grande quantità di memoria aggiuntiva. Anche se la collection originale mantiene i suoi valori in memoria, i filtri successivi no. Pertanto, praticamente nessuna memoria aggiuntiva sarà allocata durante il filtraggio dei risultati della collection.

macro()

Il metodo statico macro permette di aggiungere metodi alla classe Collection durante l’esecuzione. Consulta la documentazione su estendere le collezioni per maggiori informazioni.

make()

Il metodo statico make crea una nuova istanza di collection. Consulta la sezione Creare Collections.

map()

Il metodo map itera attraverso la collezione e passa ogni valore alla callback fornita. La callback può modificare l’elemento e restituirlo, formando così una nuova collezione di elementi modificati:

$collection = collect([1, 2, 3, 4, 5]);

$multiplied = $collection->map(function (int $item, int $key) {
    return $item * 2;
});

$multiplied->all();

// [2, 4, 6, 8, 10]

Come la maggior parte degli altri metodi della collezione, map ritorna una nuova istanza di collezione; non modifica la collezione su cui viene chiamato. Se vuoi trasformare la collezione originale, usa il metodo transform.

mapInto()

Il metodo mapInto() itera sulla collezione, creando una nuova istanza della classe specificata passando il valore al costruttore:

class Currency
{
    /**
     * Crea una nuova istanza di valuta.
     */
    function __construct(
        public string $code,
    ) {}
}

$collection = collect(['USD', 'EUR', 'GBP']);

$currencies = $collection->mapInto(Currency::class);

$currencies->all();

// [Currency('USD'), Currency('EUR'), Currency('GBP')]

mapSpread()

Il metodo mapSpread itera sugli elementi della collection, passando ciascun valore dell’elemento nidificato nella closure fornita. La closure può modificare l’elemento e restituirlo, formando così una nuova collection di elementi modificati:

$collection = collect([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]);

$chunks = $collection->chunk(2);

$sequence = $chunks->mapSpread(function (int $even, int $odd) {
    return $even + $odd;
});

$sequence->all();

// [1, 5, 9, 13, 17]

mapToGroups()

Il metodo mapToGroups raggruppa gli elementi della collection utilizzando la closure fornita. La closure deve restituire un array associativo contenente una singola coppia chiave/valore, formando così una nuova collection di valori raggruppati:

$collection = collect([
    [
        'name' => 'John Doe',
        'department' => 'Sales',
    ],
    [
        'name' => 'Jane Doe',
        'department' => 'Sales',
    ],
    [
        'name' => 'Johnny Doe',
        'department' => 'Marketing',
    ]
]);

$grouped = $collection->mapToGroups(function (array $item, int $key) {
    return [$item['department'] => $item['name']];
});

$grouped->all();

/*
    [
        'Sales' => ['John Doe', 'Jane Doe'],
        'Marketing' => ['Johnny Doe'],
    ]
*/

$grouped->get('Sales')->all();

// ['John Doe', 'Jane Doe']

mapWithKeys()

Il metodo mapWithKeys itera attraverso la collezione e passa ogni valore al callback fornito. Il callback dovrebbe restituire un array associativo contenente una singola coppia chiave/valore:

    $collection = collect([
        [
            'name' => 'John',
            'department' => 'Sales',
            'email' => 'john@example.com',
        ],
        [
            'name' => 'Jane',
            'department' => 'Marketing',
            'email' => 'jane@example.com',
        ]
    ]);

    $keyed = $collection->mapWithKeys(function (array $item, int $key) {
        return [$item['email'] => $item['name']];
    });

    $keyed->all();

    /*
        [
            'john@example.com' => 'John',
            'jane@example.com' => 'Jane',
        ]
    */

max()

Il metodo max restituisce il valore massimo di una chiave specifica:

    $max = collect([
        ['foo' => 10],
        ['foo' => 20]
    ])->max('foo');
    
    // 20
    
    $max = collect([1, 2, 3, 4, 5])->max();
    
    // 5

median()

Il metodo median restituisce il valore mediano per una chiave specifica:

$median = collect([
    ['foo' => 10],
    ['foo' => 10],
    ['foo' => 20],
    ['foo' => 40]
])->median('foo');

// 15

$median = collect([1, 1, 2, 4])->median();

// 1.5

merge()

Il metodo merge unisce l’array o la collezione fornita con la collezione originale. Se una chiave stringa negli elementi forniti corrisponde a una chiave stringa nella collezione originale, il valore dell’elemento fornito sovrascriverà quello nella collezione originale:

$collection = collect(['product_id' => 1, 'price' => 100]);

$merged = $collection->merge(['price' => 200, 'discount' => false]);

$merged->all();

// ['product_id' => 1, 'price' => 200, 'discount' => false]

Se le chiavi degli elementi forniti sono numeriche, i valori verranno aggiunti alla fine della collezione:

$collection = collect(['Desk', 'Chair']);

$merged = $collection->merge(['Bookcase', 'Door']);

$merged->all();

// ['Desk', 'Chair', 'Bookcase', 'Door']

mergeRecursive()

Il metodo mergeRecursive unisce ricorsivamente l’array o la collezione fornita con la collezione originale. Se una chiave stringa negli elementi dati corrisponde a una chiave stringa nella collezione originale, i valori di queste chiavi vengono combinati in un array, e questo processo si ripete ricorsivamente:

$collection = collect(['product_id' => 1, 'price' => 100]);

$merged = $collection->mergeRecursive([
    'product_id' => 2,
    'price' => 200,
    'discount' => false
]);

$merged->all();

// ['product_id' => [1, 2], 'price' => [100, 200], 'discount' => false]

min()

Il metodo min restituisce il valore minimo di una determinata chiave:

$min = collect([['foo' => 10], ['foo' => 20]])->min('foo');

// 10

$min = collect([1, 2, 3, 4, 5])->min();

// 1

mode()

Il metodo mode restituisce il mode value di una determinata chiave:

    $mode = collect([
        ['foo' => 10],
        ['foo' => 10],
        ['foo' => 20],
        ['foo' => 40]
    ])->mode('foo');

    // [10]

    $mode = collect([1, 1, 2, 4])->mode();

    // [1]

    $mode = collect([1, 1, 2, 2])->mode();

    // [1, 2]

multiply()

Il metodo multiply crea il numero specificato di copie di tutti gli elementi nella collezione:

$users = collect([
    ['name' => 'User #1', 'email' => 'user1@example.com'],
    ['name' => 'User #2', 'email' => 'user2@example.com'],
])->multiply(3);

/*
    [
        ['name' => 'User #1', 'email' => 'user1@example.com'],
        ['name' => 'User #2', 'email' => 'user2@example.com'],
        ['name' => 'User #1', 'email' => 'user1@example.com'],
        ['name' => 'User #2', 'email' => 'user2@example.com'],
        ['name' => 'User #1', 'email' => 'user1@example.com'],
        ['name' => 'User #2', 'email' => 'user2@example.com'],
    ]
*/

nth()

Il metodo nth crea una nuova collezione composta da ogni n-esimo elemento:

    $collection = collect(['a', 'b', 'c', 'd', 'e', 'f']);

    $collection->nth(4);

    // ['a', 'e']

Puoi opzionalmente passare un offset iniziale come secondo argomento:

    $collection->nth(4, 1);

    // ['b', 'f']

only()

Il metodo only restituisce gli elementi nella collezione con le chiavi specificate:

$collection = collect([
    'product_id' => 1,
    'name' => 'Desk',
    'price' => 100,
    'discount' => false
]);

$filtered = $collection->only(['product_id', 'name']);

$filtered->all();

// ['product_id' => 1, 'name' => 'Desk']

Per l’inverso di only, vedi il metodo except.

Il comportamento di questo metodo viene modificato quando si utilizzano le Eloquent Collections.

pad()

Il metodo pad riempie l’array con il valore fornito fino a raggiungere la dimensione specificata. Questo metodo si comporta come la funzione PHP array_pad.

Per aggiungere padding a sinistra, devi specificare una dimensione negativa. Non verrà eseguito alcun padding se il valore assoluto della dimensione data è minore o uguale alla lunghezza dell’array:

    $collection = collect(['A', 'B', 'C']);

    $filtered = $collection->pad(5, 0);

    $filtered->all();

    // ['A', 'B', 'C', 0, 0]

    $filtered = $collection->pad(-5, 0);

    $filtered->all();

    // [0, 0, 'A', 'B', 'C']

partition()

Il metodo partition può essere combinato con la distrutturazione degli array di PHP per separare gli elementi che soddisfano un dato test di verità da quelli che non lo fanno:

$collection = collect([1, 2, 3, 4, 5, 6]);

[$underThree, $equalOrAboveThree] = $collection->partition(function (int $i) {
    return $i < 3;
});

$underThree->all();

// [1, 2]

$equalOrAboveThree->all();

// [3, 4, 5, 6]

percentage()

Il metodo percentage può essere utilizzato per determinare rapidamente la percentuale di elementi nella collezione che superano un determinato test:

$collection = collect([1, 1, 2, 2, 2, 3]);

$percentage = $collection->percentage(fn ($value) => $value === 1);

// 33.33

Per impostazione predefinita, la percentuale verrà arrotondata a due decimali. Tuttavia, puoi personalizzare questo comportamento passando un secondo argomento al metodo:

$percentage = $collection->percentage(fn ($value) => $value === 1, precision: 3);

// 33.333

pipe()

Il metodo pipe passa la collezione alla closure specificata e restituisce il risultato della closure eseguita:

$collection = collect([1, 2, 3]);

$piped = $collection->pipe(function (Collection $collection) {
    return $collection->sum();
});

// 6

pipeInto()

Il metodo pipeInto crea una nuova istanza della classe specificata e passa la collezione al costruttore:

class ResourceCollection
{
    /**
     * Create a new ResourceCollection instance.
     */
    public function __construct(
        public Collection $collection,
    ) {}
}

$collection = collect([1, 2, 3]);

$resource = $collection->pipeInto(ResourceCollection::class);

$resource->collection->all();

// [1, 2, 3]

pipeThrough()

Il metodo pipeThrough passa la collection all’array di closure fornito e restituisce il risultato delle closure eseguite:

use Illuminate\Support\Collection;

$collection = collect([1, 2, 3]);

$result = $collection->pipeThrough([
    function (Collection $collection) {
        return $collection->merge([4, 5]);
    },
    function (Collection $collection) {
        return $collection->sum();
    },
]);

// 15

pluck()

Il metodo pluck recupera tutti i valori per una determinata chiave:

    $collection = collect([
        ['product_id' => 'prod-100', 'name' => 'Desk'],
        ['product_id' => 'prod-200', 'name' => 'Chair'],
    ]);

    $plucked = $collection->pluck('name');

    $plucked->all();

    // ['Desk', 'Chair']

Puoi anche specificare come desideri che la collezione risultante sia indicizzata:

    $plucked = $collection->pluck('name', 'product_id');

    $plucked->all();

    // ['prod-100' => 'Desk', 'prod-200' => 'Chair']

Il metodo pluck supporta anche il recupero di valori annidati utilizzando la notazione "puntata":

    $collection = collect([
        [
            'name' => 'Laracon',
            'speakers' => [
                'first_day' => ['Rosa', 'Judith'],
            ],
        ],
        [
            'name' => 'VueConf',
            'speakers' => [
                'first_day' => ['Abigail', 'Joey'],
            ],
        ],
    ]);

    $plucked = $collection->pluck('speakers.first_day');

    $plucked->all();

    // [['Rosa', 'Judith'], ['Abigail', 'Joey']]

Se esistono chiavi duplicate, l’ultimo elemento corrispondente verrà inserito nella collezione plucked:

    $collection = collect([
        ['brand' => 'Tesla',  'color' => 'red'],
        ['brand' => 'Pagani', 'color' => 'white'],
        ['brand' => 'Tesla',  'color' => 'black'],
        ['brand' => 'Pagani', 'color' => 'orange'],
    ]);

    $plucked = $collection->pluck('color', 'brand');

    $plucked->all();

    // ['Tesla' => 'black', 'Pagani' => 'orange']

pop()

Il metodo pop rimuove e restituisce l’ultimo elemento dalla collezione:

$collection = collect([1, 2, 3, 4, 5]);

$collection->pop();

// 5

$collection->all();

// [1, 2, 3, 4]

Puoi passare un intero al metodo pop per rimuovere e restituire più elementi dalla fine della collezione:

$collection = collect([1, 2, 3, 4, 5]);

$collection->pop(3);

// collect([5, 4, 3])

$collection->all();

// [1, 2]

prepend()

Il metodo prepend aggiunge un elemento all’inizio della collezione:

    $collection = collect([1, 2, 3, 4, 5]);

    $collection->prepend(0);

    $collection->all();

    // [0, 1, 2, 3, 4, 5]

Puoi anche passare un secondo argomento per specificare la chiave dell’elemento aggiunto:

    $collection = collect(['one' => 1, 'two' => 2]);

    $collection->prepend(0, 'zero');

    $collection->all();

    // ['zero' => 0, 'one' => 1, 'two' => 2]

pull()

Il metodo pull rimuove e restituisce un elemento dalla collezione in base alla sua chiave:

    $collection = collect(['product_id' => 'prod-100', 'name' => 'Desk']);

    $collection->pull('name');

    // 'Desk'

    $collection->all();

    // ['product_id' => 'prod-100']

push()

Il metodo push aggiunge un elemento alla fine della collection:

$collection = collect([1, 2, 3, 4]);

$collection->push(5);

$collection->all();

// [1, 2, 3, 4, 5]

put()

Il metodo put imposta la chiave e il valore specificati nella collezione:

$collection = collect(['product_id' => 1, 'name' => 'Desk']);

$collection->put('price', 100);

$collection->all();

// ['product_id' => 1, 'name' => 'Desk', 'price' => 100]

random()

Il metodo random restituisce un elemento casuale dalla collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->random();

// 4 - (recuperato casualmente)

Puoi passare un numero intero a random per specificare quanti elementi vuoi recuperare casualmente. Viene sempre restituita una collection di elementi quando passi esplicitamente il numero di elementi che desideri ricevere:

$random = $collection->random(3);

$random->all();

// [2, 4, 5] - (recuperato casualmente)

Se l’istanza della collection ha meno elementi di quelli richiesti, il metodo random genererà un’eccezione InvalidArgumentException.

Il metodo random accetta anche una closure, che riceverà l’istanza corrente della collection:

use Illuminate\Support\Collection;

$random = $collection->random(fn (Collection $items) => min(10, count($items)));

$random->all();

// [1, 2, 3, 4, 5] - (recuperato casualmente)

range()

Il metodo range restituisce una collezione con i numeri interi compresi nell’intervallo specificato:

    $collection = collect()->range(3, 6);

    $collection->all();

    // [3, 4, 5, 6]

reduce()

Il metodo reduce riduce la collezione a un singolo valore, passando il risultato di ogni iterazione a quella successiva:

$collection = collect([1, 2, 3]);

$total = $collection->reduce(function (?int $carry, int $item) {
    return $carry + $item;
});

// 6

Il valore di $carry nella prima iterazione è null; tuttavia, puoi specificare il suo valore iniziale passando un secondo argomento a reduce:

$collection->reduce(function (int $carry, int $item) {
    return $carry + $item;
}, 4);

// 10

Il metodo reduce passa anche le chiavi degli array nelle collezioni associative al callback fornito:

$collection = collect([
    'usd' => 1400,
    'gbp' => 1200,
    'eur' => 1000,
]);

$ratio = [
    'usd' => 1,
    'gbp' => 1.37,
    'eur' => 1.22,
];

$collection->reduce(function (int $carry, int $value, int $key) use ($ratio) {
    return $carry + ($value * $ratio[$key]);
});

// 4264

reduceSpread()

Il metodo reduceSpread riduce la collection a un array di valori, passando i risultati di ogni iterazione alla successiva. Questo metodo è simile al metodo reduce; tuttavia, può accettare più valori iniziali:

[$creditsRemaining, $batch] = Image::where('status', 'unprocessed')
    ->get()
    ->reduceSpread(function (int $creditsRemaining, Collection $batch, Image $image) {
        if ($creditsRemaining >= $image->creditsRequired()) {
            $batch->push($image);

            $creditsRemaining -= $image->creditsRequired();
        }

        return [$creditsRemaining, $batch];
    }, $creditsAvailable, collect());

reject()

Il metodo reject filtra la collezione utilizzando la closure fornita. La closure deve restituire true se l’elemento deve essere rimosso dalla collezione risultante:

$collection = collect([1, 2, 3, 4]);

$filtered = $collection->reject(function (int $value, int $key) {
    return $value > 2;
});

$filtered->all();

// [1, 2]

Per l’inverso del metodo reject, consulta il metodo filter.

replace()

Il metodo replace funziona in modo simile a merge. Tuttavia, oltre a sovrascrivere gli elementi con chiavi stringa corrispondenti, replace sovrascrive anche gli elementi con chiavi numeriche corrispondenti nella collezione:

$collection = collect(['Taylor', 'Abigail', 'James']);

$replaced = $collection->replace([1 => 'Victoria', 3 => 'Finn']);

$replaced->all();

// ['Taylor', 'Victoria', 'James', 'Finn']

replaceRecursive()

Questo metodo funziona come replace, ma ricorre negli array e applica lo stesso processo di sostituzione ai valori interni:

$collection = collect([
    'Taylor',
    'Abigail',
    [
        'James',
        'Victoria',
        'Finn'
    ]
]);

$replaced = $collection->replaceRecursive([
    'Charlie',
    2 => [1 => 'King']
]);

$replaced->all();

// ['Charlie', 'Abigail', ['James', 'King', 'Finn']]

reverse()

Il metodo reverse inverte l’ordine degli elementi della collezione, mantenendo le chiavi originali:

$collection = collect(['a', 'b', 'c', 'd', 'e']);

$reversed = $collection->reverse();

$reversed->all();

/*
    [
        4 => 'e',
        3 => 'd',
        2 => 'c',
        1 => 'b',
        0 => 'a',
    ]
*/

search()

Il metodo search cerca nella collezione il valore fornito e restituisce la sua chiave se trovato. Se l’elemento non viene trovato, viene restituito false:

$collection = collect([2, 4, 6, 8]);

$collection->search(4);

// 1

La ricerca viene effettuata utilizzando un confronto "loose", il che significa che una stringa con un valore intero sarà considerata uguale a un intero dello stesso valore. Per utilizzare un confronto "strict", passa true come secondo argomento al metodo:

collect([2, 4, 6, 8])->search('4', strict: true);

// false

In alternativa, puoi fornire una closure personalizzata per cercare il primo elemento che soddisfa una determinata condizione:

collect([2, 4, 6, 8])->search(function (int $item, int $key) {
    return $item > 5;
});

// 2

select()

Il metodo select seleziona le chiavi specificate dalla collezione, simile a una dichiarazione SELECT in SQL:

$users = collect([
    ['name' => 'Taylor Otwell', 'role' => 'Developer', 'status' => 'active'],
    ['name' => 'Victoria Faith', 'role' => 'Researcher', 'status' => 'active'],
]);

$users->select(['name', 'role']);

/*
    [
        ['name' => 'Taylor Otwell', 'role' => 'Developer'],
        ['name' => 'Victoria Faith', 'role' => 'Researcher'],
    ],
*/

shift()

Il metodo shift rimuove e restituisce il primo elemento dalla collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->shift();

// 1

$collection->all();

// [2, 3, 4, 5]

Puoi passare un intero al metodo shift per rimuovere e restituire più elementi dall’inizio di una collection:

$collection = collect([1, 2, 3, 4, 5]);

$collection->shift(3);

// collect([1, 2, 3])

$collection->all();

// [4, 5]

shuffle()

Il metodo shuffle mescola casualmente gli elementi nella collezione:

$collection = collect([1, 2, 3, 4, 5]);

$shuffled = $collection->shuffle();

$shuffled->all();

// [3, 2, 5, 1, 4] - (generato casualmente)

skip()

Il metodo skip restituisce una nuova collezione, con il numero specificato di elementi rimossi dall’inizio della collezione:

    $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

    $collection = $collection->skip(4);

    $collection->all();

    // [5, 6, 7, 8, 9, 10]

skipUntil()

Il metodo skipUntil salta gli elementi della collezione finché il callback dato restituisce false. Una volta che il callback restituisce true, tutti gli elementi rimanenti della collezione verranno restituiti come una nuova collezione:

$collection = collect([1, 2, 3, 4]);

$subset = $collection->skipUntil(function (int $item) {
    return $item >= 3;
});

$subset->all();

// [3, 4]

Puoi anche passare un valore semplice al metodo skipUntil per saltare tutti gli elementi fino a quando non viene trovato il valore dato:

$collection = collect([1, 2, 3, 4]);

$subset = $collection->skipUntil(3);

$subset->all();

// [3, 4]

Se il valore dato non viene trovato o il callback non restituisce mai true, il metodo skipUntil restituirà una collezione vuota.

skipWhile()

Il metodo skipWhile ignora gli elementi della collezione finché la callback fornita ritorna true. Una volta che la callback ritorna false, tutti gli elementi rimanenti nella collezione vengono restituiti come una nuova collezione:

    $collection = collect([1, 2, 3, 4]);

    $subset = $collection->skipWhile(function (int $item) {
        return $item <= 3;
    });

    $subset->all();

    // [4]

Se la callback non ritorna mai false, il metodo skipWhile restituirà una collezione vuota.

slice()

Il metodo slice restituisce una porzione della collezione a partire dall’indice specificato:

$collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

$slice = $collection->slice(4);

$slice->all();

// [5, 6, 7, 8, 9, 10]

Se vuoi limitare la dimensione della porzione restituita, passa la dimensione desiderata come secondo argomento al metodo:

$slice = $collection->slice(4, 2);

$slice->all();

// [5, 6]

La porzione restituita manterrà le chiavi per default. Se non vuoi preservare le chiavi originali, puoi usare il metodo values per reindicizzarle.

sliding()

Il metodo sliding restituisce una nuova collezione di segmenti che rappresentano una vista a "finestra mobile" degli elementi nella collezione:

$collection = collect([1, 2, 3, 4, 5]);

$chunks = $collection->sliding(2);

$chunks->toArray();

// [[1, 2], [2, 3], [3, 4], [4, 5]]

Questo è particolarmente utile insieme al metodo eachSpread:

$transactions->sliding(2)->eachSpread(function (Collection $previous, Collection $current) {
    $current->total = $previous->total + $current->amount;
});

Puoi opzionalmente passare un secondo valore "step", che determina la distanza tra il primo elemento di ogni segmento:

$collection = collect([1, 2, 3, 4, 5]);

$chunks = $collection->sliding(3, step: 2);

$chunks->toArray();

// [[1, 2, 3], [3, 4, 5]]

sole()

Il metodo sole restituisce il primo elemento nella collezione che supera un determinato test, ma solo se il test corrisponde esattamente a un elemento:

    collect([1, 2, 3, 4])->sole(function (int $value, int $key) {
        return $value === 2;
    });

    // 2

Puoi anche passare una coppia chiave/valore al metodo sole, che restituirà il primo elemento nella collezione che corrisponde alla coppia specificata, ma solo se esattamente un elemento corrisponde:

    $collection = collect([
        ['product' => 'Desk', 'price' => 200],
        ['product' => 'Chair', 'price' => 100],
    ]);

    $collection->sole('product', 'Chair');

    // ['product' => 'Chair', 'price' => 100]

In alternativa, puoi chiamare il metodo sole senza argomenti per ottenere il primo elemento della collezione se c’è un solo elemento:

    $collection = collect([
        ['product' => 'Desk', 'price' => 200],
    ]);

    $collection->sole();

    // ['product' => 'Desk', 'price' => 200]

Se non ci sono elementi nella collezione che devono essere restituiti dal metodo sole, verrà lanciata un’eccezione \Illuminate\Collections\ItemNotFoundException. Se c’è più di un elemento che dovrebbe essere restituito, verrà lanciata un’eccezione \Illuminate\Collections\MultipleItemsFoundException.

some()

Alias del metodo contains.

sort()

Il metodo sort ordina la collection. La collection ordinata mantiene le chiavi originali dell’array, quindi nell’esempio seguente utilizzeremo il metodo values per reimpostare le chiavi a indici numerati consecutivamente:

    $collection = collect([5, 3, 1, 2, 4]);

    $sorted = $collection->sort();

    $sorted->values()->all();

    // [1, 2, 3, 4, 5]

Se le tue esigenze di ordinamento sono più avanzate, puoi passare una callback a sort con il tuo algoritmo personalizzato. Consulta la documentazione PHP su uasort, che è ciò che utilizza internamente il metodo sort della collection.

Se hai bisogno di ordinare una collection di array o oggetti nidificati, vedi i metodi sortBy e sortByDesc.

sortBy()

Il metodo sortBy ordina la collezione in base alla chiave specificata. La collezione ordinata mantiene le chiavi originali dell’array, quindi nell’esempio seguente utilizzeremo il metodo values per reimpostare le chiavi su indici numerati consecutivamente:

$collection = collect([
    ['name' => 'Desk', 'price' => 200],
    ['name' => 'Chair', 'price' => 100],
    ['name' => 'Bookcase', 'price' => 150],
]);

$sorted = $collection->sortBy('price');

$sorted->values()->all();

/*
    [
        ['name' => 'Chair', 'price' => 100],
        ['name' => 'Bookcase', 'price' => 150],
        ['name' => 'Desk', 'price' => 200],
    ]
*/

Il metodo sortBy accetta flag di ordinamento come secondo argomento:

$collection = collect([
    ['title' => 'Item 1'],
    ['title' => 'Item 12'],
    ['title' => 'Item 3'],
]);

$sorted = $collection->sortBy('title', SORT_NATURAL);

$sorted->values()->all();

/*
    [
        ['title' => 'Item 1'],
        ['title' => 'Item 3'],
        ['title' => 'Item 12'],
    ]
*/

In alternativa, puoi passare una tua closure per determinare come ordinare i valori della collezione:

$collection = collect([
    ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
    ['name' => 'Chair', 'colors' => ['Black']],
    ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
]);

$sorted = $collection->sortBy(function (array $product, int $key) {
    return count($product['colors']);
});

$sorted->values()->all();

/*
    [
        ['name' => 'Chair', 'colors' => ['Black']],
        ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
        ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
    ]
*/

Se desideri ordinare la tua collezione per più attributi, puoi passare un array di operazioni di ordinamento al metodo sortBy. Ogni operazione di ordinamento deve essere un array composto dall’attributo su cui ordinare e dalla direzione dell’ordinamento desiderato:

$collection = collect([
    ['name' => 'Taylor Otwell', 'age' => 34],
    ['name' => 'Abigail Otwell', 'age' => 30],
    ['name' => 'Taylor Otwell', 'age' => 36],
    ['name' => 'Abigail Otwell', 'age' => 32],
]);

$sorted = $collection->sortBy([
    ['name', 'asc'],
    ['age', 'desc'],
]);

$sorted->values()->all();

/*
    [
        ['name' => 'Abigail Otwell', 'age' => 32],
        ['name' => 'Abigail Otwell', 'age' => 30],
        ['name' => 'Taylor Otwell', 'age' => 36],
        ['name' => 'Taylor Otwell', 'age' => 34],
    ]
*/

Quando ordini una collezione per più attributi, puoi anche fornire delle closure che definiscono ciascuna operazione di ordinamento:

$collection = collect([
    ['name' => 'Taylor Otwell', 'age' => 34],
    ['name' => 'Abigail Otwell', 'age' => 30],
    ['name' => 'Taylor Otwell', 'age' => 36],
    ['name' => 'Abigail Otwell', 'age' => 32],
]);

$sorted = $collection->sortBy([
    fn (array $a, array $b) => $a['name'] <=> $b['name'],
    fn (array $a, array $b) => $b['age'] <=> $a['age'],
]);

$sorted->values()->all();

/*
    [
        ['name' => 'Abigail Otwell', 'age' => 32],
        ['name' => 'Abigail Otwell', 'age' => 30],
        ['name' => 'Taylor Otwell', 'age' => 36],
        ['name' => 'Taylor Otwell', 'age' => 34],
    ]
*/

sortByDesc()

Questo metodo ha la stessa firma del metodo sortBy, ma ordina la collezione nell’ordine opposto.

sortDesc()

Questo metodo ordina la collezione in ordine inverso rispetto al metodo sort:

$collection = collect([5, 3, 1, 2, 4]);

$sorted = $collection->sortDesc();

$sorted->values()->all();

// [5, 4, 3, 2, 1]

A differenza di sort, non puoi passare una closure a sortDesc. Invece, dovresti usare il metodo sort e invertire il confronto.

sortKeys()

Il metodo sortKeys ordina la collezione in base alle chiavi dell’array associativo sottostante:

$collection = collect([
    'id' => 22345,
    'first' => 'John',
    'last' => 'Doe',
]);

$sorted = $collection->sortKeys();

$sorted->all();

/*
    [
        'first' => 'John',
        'id' => 22345,
        'last' => 'Doe',
    ]
*/

sortKeysDesc()

Questo metodo ha la stessa firma del metodo sortKeys, ma ordina la collezione nell’ordine opposto.

sortKeysUsing()

Il metodo sortKeysUsing ordina la collezione in base alle chiavi dell’array associativo sottostante utilizzando una callback:

$collection = collect([
    'ID' => 22345,
    'first' => 'John',
    'last' => 'Doe',
]);

$sorted = $collection->sortKeysUsing('strnatcasecmp');

$sorted->all();

/*
    [
        'first' => 'John',
        'ID' => 22345,
        'last' => 'Doe',
    ]
*/

La callback deve essere una funzione di confronto che restituisce un intero minore, uguale o maggiore di zero. Per maggiori informazioni, consulta la documentazione PHP su uksort, che è la funzione PHP utilizzata internamente dal metodo sortKeysUsing.

splice()

Il metodo splice rimuove e restituisce una porzione di elementi a partire dall’indice specificato:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2);

$chunk->all();

// [3, 4, 5]

$collection->all();

// [1, 2]

Puoi passare un secondo argomento per limitare la dimensione della collezione risultante:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2, 1);

$chunk->all();

// [3]

$collection->all();

// [1, 2, 4, 5]

Inoltre, puoi passare un terzo argomento contenente i nuovi elementi per sostituire quelli rimossi dalla collezione:

$collection = collect([1, 2, 3, 4, 5]);

$chunk = $collection->splice(2, 1, [10, 11]);

$chunk->all();

// [3]

$collection->all();

// [1, 2, 10, 11, 4, 5]

split()

Il metodo split divide una collezione nel numero di gruppi specificato:

$collection = collect([1, 2, 3, 4, 5]);

$groups = $collection->split(3);

$groups->all();

// [[1, 2], [3, 4], [5]]

splitIn()

Il metodo splitIn suddivide una collezione nel numero specificato di gruppi, riempiendo completamente i gruppi non finali prima di assegnare il resto all’ultimo gruppo:

    $collection = collect([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]);

    $groups = $collection->splitIn(3);

    $groups->all();

    // [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10]]

sum()

Il metodo sum restituisce la somma di tutti gli elementi nella collection:

    collect([1, 2, 3, 4, 5])->sum();

    // 15

Se la collection contiene array nidificati o oggetti, devi passare una chiave che verrà utilizzata per determinare quali valori sommare:

    $collection = collect([
        ['name' => 'JavaScript: The Good Parts', 'pages' => 176],
        ['name' => 'JavaScript: The Definitive Guide', 'pages' => 1096],
    ]);

    $collection->sum('pages');

    // 1272

Inoltre, puoi passare una tua closure per determinare quali valori della collection sommare:

    $collection = collect([
        ['name' => 'Chair', 'colors' => ['Black']],
        ['name' => 'Desk', 'colors' => ['Black', 'Mahogany']],
        ['name' => 'Bookcase', 'colors' => ['Red', 'Beige', 'Brown']],
    ]);

    $collection->sum(function (array $product) {
        return count($product['colors']);
    });

    // 6

take()

Il metodo take restituisce una nuova collezione con il numero specificato di elementi:

$collection = collect([0, 1, 2, 3, 4, 5]);

$chunk = $collection->take(3);

$chunk->all();

// [0, 1, 2]

Puoi anche passare un intero negativo per prendere il numero specificato di elementi dalla fine della collezione:

$collection = collect([0, 1, 2, 3, 4, 5]);

$chunk = $collection->take(-2);

$chunk->all();

// [4, 5]

takeUntil()

Il metodo takeUntil restituisce gli elementi nella collection fino a quando la callback fornita restituisce true:

$collection = collect([1, 2, 3, 4]);

$subset = $collection->takeUntil(function (int $item) {
    return $item >= 3;
});

$subset->all();

// [1, 2]

Puoi anche passare un valore semplice al metodo takeUntil per ottenere gli elementi fino a quando non viene trovato il valore indicato:

$collection = collect([1, 2, 3, 4]);

$subset = $collection->takeUntil(3);

$subset->all();

// [1, 2]

Se il valore indicato non viene trovato o la callback non restituisce mai true, il metodo takeUntil restituirà tutti gli elementi nella collection.

takeWhile()

Il metodo takeWhile restituisce gli elementi della collezione finché la callback fornita non restituisce false:

$collection = collect([1, 2, 3, 4]);

$subset = $collection->takeWhile(function (int $item) {
    return $item < 3;
});

$subset->all();

// [1, 2]

Se la callback non restituisce mai false, il metodo takeWhile restituirà tutti gli elementi della collezione.

tap()

Il metodo tap passa la collezione al callback fornito, permettendoti di "intervenire" nella collezione in un punto specifico e di fare qualcosa con gli elementi senza modificare la collezione stessa. La collezione viene quindi restituita dal metodo tap:

collect([2, 4, 3, 1, 5])
    ->sort()
    ->tap(function (Collection $collection) {
        Log::debug('Valori dopo l\'ordinamento', $collection->values()->all());
    })
    ->shift();

// 1

times()

Il metodo statico times crea una nuova collezione invocando la closure fornita un numero specificato di volte:

$collection = Collection::times(10, function (int $number) {
    return $number * 9;
});

$collection->all();

// [9, 18, 27, 36, 45, 54, 63, 72, 81, 90]

toArray()

Il metodo toArray converte la collection in un semplice array PHP. Se i valori della collection sono modelli Eloquent, anche i modelli verranno convertiti in array:

    $collection = collect(['name' => 'Desk', 'price' => 200]);

    $collection->toArray();

    /*
        [
            ['name' => 'Desk', 'price' => 200],
        ]
    */

toArray converte anche tutti gli oggetti annidati della collection che sono istanze di Arrayable in array. Se vuoi ottenere l’array grezzo sottostante alla collection, usa invece il metodo all.

toJson()

Il metodo toJson trasforma la collezione in una stringa serializzata JSON:

$collection = collect(['name' => 'Desk', 'price' => 200]);

$collection->toJson();

// '{"name":"Desk", "price":200}'

transform()

Il metodo transform itera sulla collezione e chiama la callback fornita per ogni elemento nella collezione. Gli elementi nella collezione verranno sostituiti dai valori restituiti dalla callback:

$collection = collect([1, 2, 3, 4, 5]);

$collection->transform(function (int $item, int $key) {
    return $item * 2;
});

$collection->all();

// [2, 4, 6, 8, 10]

A differenza della maggior parte degli altri metodi delle collezioni, transform modifica direttamente la collezione. Se desideri creare una nuova collezione, utilizza invece il metodo map.

undot()

Il metodo undot trasforma una collezione monodimensionale che usa la notazione a "punto" in una collezione multidimensionale:

    $person = collect([
        'name.first_name' => 'Marie',
        'name.last_name' => 'Valentine',
        'address.line_1' => '2992 Eagle Drive',
        'address.line_2' => '',
        'address.suburb' => 'Detroit',
        'address.state' => 'MI',
        'address.postcode' => '48219'
    ]);

    $person = $person->undot();

    $person->toArray();

    /*
        [
            "name" => [
                "first_name" => "Marie",
                "last_name" => "Valentine",
            ],
            "address" => [
                "line_1" => "2992 Eagle Drive",
                "line_2" => "",
                "suburb" => "Detroit",
                "state" => "MI",
                "postcode" => "48219",
            ],
        ]
    */

union()

Il metodo union aggiunge l’array fornito alla collezione. Se l’array contiene chiavi già presenti nella collezione originale, i valori della collezione originale avranno la priorità:

    $collection = collect([1 => ['a'], 2 => ['b']]);

    $union = $collection->union([3 => ['c'], 1 => ['d']]);

    $union->all();

    // [1 => ['a'], 2 => ['b'], 3 => ['c']]

unique()

Il metodo unique restituisce tutti gli elementi unici nella collezione. La collezione restituita mantiene le chiavi originali dell’array, quindi nell’esempio seguente useremo il metodo values per ripristinare le chiavi a indici numerati consecutivamente:

$collection = collect([1, 1, 2, 2, 3, 4, 2]);

$unique = $collection->unique();

$unique->values()->all();

// [1, 2, 3, 4]

Quando si lavora con array annidati o oggetti, puoi specificare la chiave usata per determinare l’unicità:

$collection = collect([
    ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
    ['name' => 'iPhone 5', 'brand' => 'Apple', 'type' => 'phone'],
    ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
    ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
    ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
]);

$unique = $collection->unique('brand');

$unique->values()->all();

/*
    [
        ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
        ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
    ]
*/

Infine, puoi anche passare una closure personalizzata al metodo unique per specificare quale valore deve determinare l’unicità di un elemento:

$unique = $collection->unique(function (array $item) {
    return $item['brand'].$item['type'];
});

$unique->values()->all();

/*
    [
        ['name' => 'iPhone 6', 'brand' => 'Apple', 'type' => 'phone'],
        ['name' => 'Apple Watch', 'brand' => 'Apple', 'type' => 'watch'],
        ['name' => 'Galaxy S6', 'brand' => 'Samsung', 'type' => 'phone'],
        ['name' => 'Galaxy Gear', 'brand' => 'Samsung', 'type' => 'watch'],
    ]
*/

Il metodo unique utilizza confronti "non rigorosi" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero con lo stesso valore. Usa il metodo uniqueStrict per filtrare utilizzando confronti "rigorosi".

Il comportamento di questo metodo viene modificato quando si utilizzano Collezioni Eloquent.

uniqueStrict()

Questo metodo ha la stessa firma del metodo unique; tuttavia, tutti i valori vengono confrontati usando confronti "stretti".

unless()

Il metodo unless eseguirà il callback fornito a meno che il primo argomento passato al metodo non sia valutato come true:

$collection = collect([1, 2, 3]);

$collection->unless(true, function (Collection $collection) {
    return $collection->push(4);
});

$collection->unless(false, function (Collection $collection) {
    return $collection->push(5);
});

$collection->all();

// [1, 2, 3, 5]

È possibile passare un secondo callback al metodo unless. Il secondo callback verrà eseguito quando il primo argomento passato al metodo unless è valutato come true:

$collection = collect([1, 2, 3]);

$collection->unless(true, function (Collection $collection) {
    return $collection->push(4);
}, function (Collection $collection) {
    return $collection->push(5);
});

$collection->all();

// [1, 2, 3, 5]

Per l’inverso di unless, vedi il metodo when.

unlessEmpty()

Alias per il metodo whenNotEmpty.

unlessNotEmpty()

Alias per il metodo whenEmpty.

unwrap()

Il metodo statico unwrap restituisce gli elementi sottostanti della collezione dal valore dato, quando applicabile:

Collection::unwrap(collect('John Doe'));

// ['John Doe']

Collection::unwrap(['John Doe']);

// ['John Doe']

Collection::unwrap('John Doe');

// 'John Doe'

value()

Il metodo value ottiene un valore specificato dal primo elemento della collezione:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Speaker', 'price' => 400],
]);

$value = $collection->value('price');

// 200

values()

Il metodo values restituisce una nuova collezione con le chiavi reimpostate a interi consecutivi:

    $collection = collect([
        10 => ['product' => 'Desk', 'price' => 200],
        11 => ['product' => 'Desk', 'price' => 200],
    ]);

    $values = $collection->values();

    $values->all();

    /*
        [
            0 => ['product' => 'Desk', 'price' => 200],
            1 => ['product' => 'Desk', 'price' => 200],
        ]
    */

when()

Il metodo when esegue la callback fornita quando il primo argomento passato al metodo è true. L’istanza della collection e il primo argomento dato al metodo when saranno forniti alla closure:

    $collection = collect([1, 2, 3]);

    $collection->when(true, function (Collection $collection, int $value) {
        return $collection->push(4);
    });

    $collection->when(false, function (Collection $collection, int $value) {
        return $collection->push(5);
    });

    $collection->all();

    // [1, 2, 3, 4]

Può essere passata una seconda callback al metodo when. La seconda callback verrà eseguita quando il primo argomento passato al metodo when è false:

    $collection = collect([1, 2, 3]);

    $collection->when(false, function (Collection $collection, int $value) {
        return $collection->push(4);
    }, function (Collection $collection) {
        return $collection->push(5);
    });

    $collection->all();

    // [1, 2, 3, 5]

Per l’inverso di when, vedi il metodo unless.

whenEmpty()

Il metodo whenEmpty esegue la callback fornita quando la collezione è vuota:

$collection = collect(['Michael', 'Tom']);

$collection->whenEmpty(function (Collection $collection) {
    return $collection->push('Adam');
});

$collection->all();

// ['Michael', 'Tom']


$collection = collect();

$collection->whenEmpty(function (Collection $collection) {
    return $collection->push('Adam');
});

$collection->all();

// ['Adam']

È possibile passare una seconda closure al metodo whenEmpty che verrà eseguita quando la collezione non è vuota:

$collection = collect(['Michael', 'Tom']);

$collection->whenEmpty(function (Collection $collection) {
    return $collection->push('Adam');
}, function (Collection $collection) {
    return $collection->push('Taylor');
});

$collection->all();

// ['Michael', 'Tom', 'Taylor']

Per l’inverso di whenEmpty, consulta il metodo whenNotEmpty.

whenNotEmpty()

Il metodo whenNotEmpty esegue la callback fornita quando la collezione non è vuota:

$collection = collect(['michael', 'tom']);

$collection->whenNotEmpty(function (Collection $collection) {
    return $collection->push('adam');
});

$collection->all();

// ['michael', 'tom', 'adam']


$collection = collect();

$collection->whenNotEmpty(function (Collection $collection) {
    return $collection->push('adam');
});

$collection->all();

// []

Può essere passata una seconda closure al metodo whenNotEmpty che verrà eseguita quando la collezione è vuota:

$collection = collect();

$collection->whenNotEmpty(function (Collection $collection) {
    return $collection->push('adam');
}, function (Collection $collection) {
    return $collection->push('taylor');
});

$collection->all();

// ['taylor']

Per l’inverso di whenNotEmpty, consulta il metodo whenEmpty.

where()

Il metodo where filtra la collezione per una specifica coppia chiave / valore:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->where('price', 100);

$filtered->all();

/*
    [
        ['product' => 'Chair', 'price' => 100],
        ['product' => 'Door', 'price' => 100],
    ]
*/

Il metodo where utilizza confronti "non stretti" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero dello stesso valore. Usa il metodo whereStrict per filtrare usando confronti "stretti".

Opzionalmente, puoi passare un operatore di confronto come secondo parametro. Gli operatori supportati sono: ‘===’, ‘!==’, ‘!=’, ‘==’, ‘=’, ‘<>’, ‘>’, ‘<‘, ‘>=’, e ‘<=’:

$collection = collect([
    ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
    ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
    ['name' => 'Sue', 'deleted_at' => null],
]);

$filtered = $collection->where('deleted_at', '!=', null);

$filtered->all();

/*
    [
        ['name' => 'Jim', 'deleted_at' => '2019-01-01 00:00:00'],
        ['name' => 'Sally', 'deleted_at' => '2019-01-02 00:00:00'],
    ]
*/

whereStrict()

Questo metodo ha la stessa firma del metodo where; tuttavia, tutti i valori vengono confrontati usando confronti "stretti".

whereBetween()

Il metodo whereBetween filtra la collezione verificando se il valore di un elemento specificato rientra in un intervallo dato:

    $collection = collect([
        ['product' => 'Desk', 'price' => 200],
        ['product' => 'Chair', 'price' => 80],
        ['product' => 'Bookcase', 'price' => 150],
        ['product' => 'Pencil', 'price' => 30],
        ['product' => 'Door', 'price' => 100],
    ]);

    $filtered = $collection->whereBetween('price', [100, 200]);

    $filtered->all();

    /*
        [
            ['product' => 'Desk', 'price' => 200],
            ['product' => 'Bookcase', 'price' => 150],
            ['product' => 'Door', 'price' => 100],
        ]
    */

whereIn()

Il metodo whereIn rimuove gli elementi dalla collezione che non hanno un valore specificato contenuto nell’array fornito:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 100],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->whereIn('price', [150, 200]);

$filtered->all();

/*
    [
        ['product' => 'Desk', 'price' => 200],
        ['product' => 'Bookcase', 'price' => 150],
    ]
*/

Il metodo whereIn utilizza confronti "non stretti" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero dello stesso valore. Usa il metodo whereInStrict per filtrare usando confronti "stretti".

whereInStrict()

Questo metodo ha la stessa firma del metodo whereIn; tuttavia, tutti i valori vengono confrontati usando confronti "stretti".

whereInstanceOf()

Il metodo whereInstanceOf filtra la collezione per un dato tipo di classe:

use App\Models\User;
use App\Models\Post;

$collection = collect([
    new User,
    new User,
    new Post,
]);

$filtered = $collection->whereInstanceOf(User::class);

$filtered->all();

// [App\Models\User, App\Models\User]

whereNotBetween()

Il metodo whereNotBetween filtra la collezione verificando se il valore di un elemento specificato è al di fuori di un intervallo dato:

$collection = collect([
    ['product' => 'Desk', 'price' => 200],
    ['product' => 'Chair', 'price' => 80],
    ['product' => 'Bookcase', 'price' => 150],
    ['product' => 'Pencil', 'price' => 30],
    ['product' => 'Door', 'price' => 100],
]);

$filtered = $collection->whereNotBetween('price', [100, 200]);

$filtered->all();

/*
    [
        ['product' => 'Chair', 'price' => 80],
        ['product' => 'Pencil', 'price' => 30],
    ]
*/

whereNotIn()

Il metodo whereNotIn rimuove gli elementi dalla collezione che hanno un valore specifico presente nell’array fornito:

    $collection = collect([
        ['product' => 'Desk', 'price' => 200],
        ['product' => 'Chair', 'price' => 100],
        ['product' => 'Bookcase', 'price' => 150],
        ['product' => 'Door', 'price' => 100],
    ]);

    $filtered = $collection->whereNotIn('price', [150, 200]);

    $filtered->all();

    /*
        [
            ['product' => 'Chair', 'price' => 100],
            ['product' => 'Door', 'price' => 100],
        ]
    */

Il metodo whereNotIn utilizza confronti "non stretti" quando verifica i valori degli elementi, il che significa che una stringa con un valore intero sarà considerata uguale a un intero con lo stesso valore. Usa il metodo whereNotInStrict per filtrare utilizzando confronti "stretti".

whereNotInStrict()

Questo metodo ha la stessa firma del metodo whereNotIn; tuttavia, tutti i valori vengono confrontati usando confronti "strict".

whereNotNull()

Il metodo whereNotNull restituisce gli elementi dalla collection in cui la chiave specificata non è null:

$collection = collect([
    ['name' => 'Desk'],
    ['name' => null],
    ['name' => 'Bookcase'],
]);

$filtered = $collection->whereNotNull('name');

$filtered->all();

/*
    [
        ['name' => 'Desk'],
        ['name' => 'Bookcase'],
    ]
*/

whereNull()

Il metodo whereNull restituisce gli elementi della collezione in cui la chiave specificata è null:

$collection = collect([
    ['name' => 'Desk'],
    ['name' => null],
    ['name' => 'Bookcase'],
]);

$filtered = $collection->whereNull('name');

$filtered->all();

/*
    [
        ['name' => null],
    ]
*/

wrap()

Il metodo statico wrap mette il valore fornito all’interno di una collection quando è possibile:

use Illuminate\Support\Collection;

$collection = Collection::wrap('John Doe');

$collection->all();

// ['John Doe']

$collection = Collection::wrap(['John Doe']);

$collection->all();

// ['John Doe']

$collection = Collection::wrap(collect('John Doe'));

$collection->all();

// ['John Doe']

zip()

Il metodo zip unisce i valori dell’array fornito con quelli della collezione originale agli indici corrispondenti:

$collection = collect(['Chair', 'Desk']);

$zipped = $collection->zip([100, 200]);

$zipped->all();

// [['Chair', 100], ['Desk', 200]]

Messaggi di Ordine Superiore

Le collezioni supportano anche i "messaggi di ordine superiore", che sono scorciatoie per eseguire azioni comuni sulle collezioni. I metodi della collezione che offrono messaggi di ordine superiore sono: average, avg, contains, each, every, filter, first, flatMap, groupBy, keyBy, map, max, min, partition, reject, skipUntil, skipWhile, some, sortBy, sortByDesc, sum, takeUntil, takeWhile e unique.

Ogni messaggio di ordine superiore può essere utilizzato come proprietà dinamica su un’istanza di collezione. Ad esempio, usiamo il messaggio di ordine superiore each per chiamare un metodo su ogni oggetto della collezione:

use App\Models\User;

$users = User::where('votes', '>', 500)->get();

$users->each->markAsVip();

Allo stesso modo, possiamo usare il messaggio di ordine superiore sum per ottenere il totale dei "votes" per una collezione di utenti:

$users = User::where('group', 'Development')->get();

return $users->sum->votes;

Lazy Collections

Introduzione

Prima di approfondire le lazy collections di Laravel, prenditi del tempo per familiarizzare con i generatori PHP.

Per integrare la già potente classe Collection, la classe LazyCollection sfrutta i generatori PHP permettendoti di lavorare con dataset molto grandi mantenendo basso l’utilizzo della memoria.

Ad esempio, immagina che la tua applicazione debba elaborare un file di log di diversi gigabyte utilizzando i metodi delle collection di Laravel per analizzare i log. Invece di leggere l’intero file in memoria in una volta sola, le lazy collections possono essere utilizzate per mantenere solo una piccola parte del file in memoria alla volta:

    use App\Models\LogEntry;
    use Illuminate\Support\LazyCollection;

    LazyCollection::make(function () {
        $handle = fopen('log.txt', 'r');

        while (($line = fgets($handle)) !== false) {
            yield $line;
        }
    })->chunk(4)->map(function (array $lines) {
        return LogEntry::fromLines($lines);
    })->each(function (LogEntry $logEntry) {
        // Process the log entry...
    });

Oppure, immagina di dover iterare attraverso 10.000 modelli Eloquent. Utilizzando le collection tradizionali di Laravel, tutti e 10.000 i modelli Eloquent devono essere caricati in memoria allo stesso tempo:

    use App\Models\User;

    $users = User::all()->filter(function (User $user) {
        return $user->id > 500;
    });

Tuttavia, il metodo cursor del query builder restituisce un’istanza di LazyCollection. Questo ti permette di eseguire ancora una sola query al database ma anche di mantenere solo un modello Eloquent caricato in memoria alla volta. In questo esempio, il callback filter non viene eseguito fino a quando non iteriamo realmente su ogni utente singolarmente, permettendo una riduzione drastica dell’utilizzo della memoria:

    use App\Models\User;

    $users = User::cursor()->filter(function (User $user) {
        return $user->id > 500;
    });

    foreach ($users as $user) {
        echo $user->id;
    }

Creare Lazy Collections

Per creare un’istanza di Lazy Collection, devi passare una funzione generatore PHP al metodo make della collezione:

use Illuminate\Support\LazyCollection;

LazyCollection::make(function () {
    $handle = fopen('log.txt', 'r');

    while (($line = fgets($handle)) !== false) {
        yield $line;
    }
});

Il Contratto Enumerable

Quasi tutti i metodi disponibili nella classe Collection sono disponibili anche nella classe LazyCollection. Entrambe queste classi implementano il contratto Illuminate\Support\Enumerable, che definisce i seguenti metodi:

I metodi che mutano la collection (come shift, pop, prepend ecc.) non sono disponibili nella classe LazyCollection.

Metodi della Lazy Collection

Oltre ai metodi definiti nel contratto Enumerable, la classe LazyCollection contiene i seguenti metodi:

takeUntilTimeout()

Il metodo takeUntilTimeout restituisce una nuova lazy collection che enumererà i valori fino al tempo specificato. Dopo quel tempo, la collection smetterà di enumerare:

$lazyCollection = LazyCollection::times(INF)
    ->takeUntilTimeout(now()->addMinute());

$lazyCollection->each(function (int $number) {
    dump($number);

    sleep(1);
});

// 1
// 2
// ...
// 58
// 59

Per illustrare l’uso di questo metodo, immagina un’applicazione che invia fatture dal database utilizzando un cursor. Potresti definire un task schedulato che viene eseguito ogni 15 minuti e processa le fatture per un massimo di 14 minuti:

use App\Models\Invoice;
use Illuminate\Support\Carbon;

Invoice::pending()->cursor()
    ->takeUntilTimeout(
        Carbon::createFromTimestamp(LARAVEL_START)->add(14, 'minutes')
    )
    ->each(fn (Invoice $invoice) => $invoice->submit());

tapEach()

Mentre il metodo each chiama immediatamente la callback fornita per ogni elemento nella collezione, il metodo tapEach chiama la callback solo quando gli elementi vengono estratti dalla lista uno alla volta:

// Finora non è stato fatto nulla...
$lazyCollection = LazyCollection::times(INF)->tapEach(function (int $value) {
    dump($value);
});

// Vengono estratti tre elementi...
$array = $lazyCollection->take(3)->all();

// 1
// 2
// 3

throttle()

Il metodo throttle regola la raccolta pigramente in modo che ogni valore venga restituito dopo il numero specificato di secondi. Questo metodo è particolarmente utile in situazioni in cui si interagisce con API esterne che limitano il numero di richieste in arrivo:

use App\Models\User;

User::where('vip', true)
    ->cursor()
    ->throttle(seconds: 1)
    ->each(function (User $user) {
        // Call external API...
    });

remember()

Il metodo remember restituisce una nuova collezione lazy che memorizza i valori già enumerati e non li recupera nuovamente nelle enumerazioni successive della collezione:

// Nessuna query è stata ancora eseguita...
$users = User::cursor()->remember();

// La query viene eseguita...
// I primi 5 utenti vengono caricati dal database...
$users->take(5)->all();

// I primi 5 utenti provengono dalla cache della collezione...
// Il resto viene caricato dal database...
$users->take(20)->all();
Lascia un commento

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *