49

I have the following array in PHP:

[
  {
     "website": "example",
     "url": "example.com"
  },
  {
     "website": "example",
     "url": "example.com"
  }
]

Now I would like to convert this to a collection so I sort by the keys website or url. However when I do this:

$myArray = collect(websites);

I get this instead:

 {
      "0": {
         "website": "example",
         "url": "example.com"
      },
      "1": {
         "website": "example",
         "url": "example.com"
      }
    }

And the sorting does not work, I would like to know what I am doing wrong and how I can fix it so I have an array collection of objects I can easily sort.

Edit: I expect the output to be the same as this:

[
  {
     "website": "example",
     "url": "example.com"
  },
  {
     "website": "example",
     "url": "example.com"
  }
]

By "sorting does not work" I meant the items are not sorted.

user3718908x100
  • 7,939
  • 15
  • 64
  • 123
  • What do you expect the output to be – Jonathan Mar 03 '18 at 11:19
  • And what do you mean by "the sorting does not work"? – Joel Hinz Mar 03 '18 at 11:22
  • What I posted on top, didn't expect it to change from the original – user3718908x100 Mar 03 '18 at 11:22
  • Your question makes no sense in its current form – Jonathan Mar 03 '18 at 11:22
  • It didn't change, though. Your normal array has indices too. – Joel Hinz Mar 03 '18 at 11:22
  • Edited my post, and it did change because that is how it is being returned to the client which is a problem because it reads that as an object with the keys 0,1........etc. instead of an array of objects – user3718908x100 Mar 03 '18 at 11:25
  • 1) The thing is, your first array has numeric keys as well, even if they don't show in your print-out above. 2) A collection is an object, you can't have a collection and not want it to be an object. 3) Your array does not appear to contain objects either, although it's hard to tell for sure depending on how you print the results. – Joel Hinz Mar 03 '18 at 11:28
  • I know that however that is the response being returned to the client and there is a big difference between a json object and a json array. – user3718908x100 Mar 03 '18 at 11:29
  • Well, if you have a collection and you want specific output, you want to use the `->map()` method on collections: https://laravel.com/docs/5.6/collections#method-map – Joel Hinz Mar 03 '18 at 11:33
  • This might help. [https://stackoverflow.com/questions/51488623/how-can-i-convert-array-two-dimensional-to-collection-laravel/54785375#54785375](https://stackoverflow.com/questions/51488623/how-can-i-convert-array-two-dimensional-to-collection-laravel/54785375#54785375) – Codedreamer Feb 20 '19 at 11:36

2 Answers2

94

Edit; I understand this question is getting a lot of hits based on the title so the TLDR for those people is to use the collect() helper to create a Collection instance. In answer to the questioner's brief:

If you have

$collection = collect([
    (object) [
        'website' => 'twitter',
        'url' => 'twitter.com'
    ],
    (object) [
        'website' => 'google',
        'url' => 'google.com'
    ]
]);

You then have your array wrapped in an instance of the Collection class. That means it does not behave like a typical array (- it will be array-like, but don't treat it like it is one -) until you call all() or toArray() on it. To remove any added indices you need to use values().

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

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

The expected output:

[
     {#769
       +"website": "google",
       +"url": "google.com",
     },
     {#762
       +"website": "twitter",
       +"url": "twitter.com",
     },
]

See the docs https://laravel.com/docs/5.1/collections#available-methods

The toArray method converts the collection into a plain PHP array. If the collection's values are Eloquent models, the models will also be converted to arrays.

The all method returns the underlying array represented by the collection.

Jonathan
  • 10,936
  • 8
  • 64
  • 79
  • 2
    Exactly what I wanted! Thank you, I understand how it works now and it worked when I tested it. :) – user3718908x100 Mar 03 '18 at 11:34
  • 24
    Short answer: Use `collect($arr)`. – HartleySan Mar 08 '19 at 16:32
  • 2
    Short answer extended: There are different collections. 1. collect(array $array) or 2. new \Illuminate\Database\Eloquent\Collection(array $array). First returned collection from type Illuminate\Database\Eloquent\Collection. In some cases, however, you need the Eloquent Database Collection, then you take the second one. – Maik Lowrey Aug 09 '21 at 16:07
18

In my case I was making an collection to fake a service for test purpose so I use

$collection = new Collection();
    foreach($items as $item){
                $collection->push((object)['prod_id' => '99',
                                           'desc'=>'xyz',
                                           'price'=>'99',
                                           'discount'=>'7.35',

                ]);

            }
AbdulBasit
  • 1,269
  • 11
  • 19