4

I'm trying to make a collection from some arrays of data:

$myCollection = collect(
    ['product_id' => 1, 'price' => 200, 'discount' => '50'],
    ['product_id' => 2, 'price' => 400, 'discount' => '50']
);

When I loop out I would like to do:

foreach ($myCollection as $product) {
    echo $product->price;
    echo $product->discount;
}

But the underlying elements appear to still be in an arrays format, how can I achieve the above output?

panthro
  • 22,779
  • 66
  • 183
  • 324

4 Answers4

14

If you want the inner arrays to be a collection, then you can do so as follows:

$myCollection = collect([
    ['product_id' => 1, 'price' => 200, 'discount' => '50'],
    ['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
    return collect($row);
});

If you want the inner arrays to be objects, then you can do as follows:

$myCollection = collect([
    ['product_id' => 1, 'price' => 200, 'discount' => '50'],
    ['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
    return (object) $row;
});

You can also iterate over each of the results...

$myCollection = collect([
    ['product_id' => 1, 'price' => 200, 'discount' => '50'],
    ['product_id' => 2, 'price' => 400, 'discount' => '50']
])->map(function($row) {
    return (object) $row;
})->each(function($row) {
    echo sprintf('ProductId: %d, Price: %d, Discount: %s'.PHP_EOL, $row->product_id, $row->price, $row->discount);
});

Output:

ProductId: 1, Price: 200, Discount: 50
ProductId: 2, Price: 400, Discount: 50
Camilo
  • 6,504
  • 4
  • 39
  • 60
Gravy
  • 12,264
  • 26
  • 124
  • 193
  • If I want to save this output into array $arr; I have attempted to use $arr[] = "Product Id: ……" but it does not allow me to do so…. – Miracle Hades May 02 '21 at 12:15
5

Simple as you are getting a collection of an associative arrays because you are collecting arrays elements, so the collection helper doesn't want to modify it in case you need it as array.

Knowing this, if you want to collect objects you should pass an element of object type.

You can cast object data type into the array, like this:

$myCollection = collect( (object) array(
     (object)  ['product_id' => 1, 'price' => 200, 'discount' => '50'],
     (object)  ['product_id' => 2, 'price' => 400, 'discount' => '50'])
);

Then you have a collection of objects !

Troyer
  • 6,765
  • 3
  • 34
  • 62
  • Thanks, but why would you use an object, why doesnt collect just work? – panthro Feb 08 '17 at 15:27
  • @panthro You are collecting a group of associative arrays elements, so the collection helper doesn't want to modify it in case you need it as associative array. In case you want to collect objects you should pass an element of object type :) – Troyer Feb 08 '17 at 15:30
  • Ah this is the missing link i have been looking for! – Harry Bosh Jul 27 '17 at 00:36
0

Function collect() takes array of elements. You can fix your code also by enclosing all the elements into [] and then converting Collection elements to objects instead of leaving them to be arrays

    $myCollection = collect([
        (object)(['product_id' => 1, 'price' => 200, 'discount' => '50']),
        (object)(['product_id' => 2, 'price' => 400, 'discount' => '50'])
            ]
    );
    foreach ($myCollection as $product) {
        echo $product->price;
        echo $product->discount;
    }
Margus Pala
  • 8,433
  • 8
  • 42
  • 52
  • Maybe you can help me. Look at this : https://stackoverflow.com/questions/51488623/how-can-i-convert-array-two-dimensional-to-collection-laravel – moses toh Jul 24 '18 at 02:50
-1

There's a syntax error in your collection definition:

$myCollection = collect([
    ['product_id' => 1, 'price' => 200, 'discount' => '50'],
    ['product_id' => 2, 'price' => 400, 'discount' => '50']
]);

Also, since you're using a Collection, you no longer need to use a foreach loop:

$myCollection->each(function ($item) {
    echo $item['price'];
})
edcs
  • 3,847
  • 2
  • 33
  • 56