Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

divanoli's avatar

Want to flatten the collection as I wish

I an Individuals Table where i store some data for few pages by their page name and item type with a key

Schema::create('individuals', function (Blueprint $table) {
            $table->increments('id');
            $table->string('page');
            $table->string('key');
            $table->json('content');
            $table->timestamps();
        });

I select a collection by

 dd(Individuals::wherePage('home')->get(['key','content'])->toArray());

and I get this output

array:5 [▼
  0 => array:2 [▼
    "key" => "title"
    "content" => "Two Seas Residence"
  ]
  1 => array:2 [▼
    "key" => "overview"
    "content" => "["Living room with 4 sofas","Non-smoking rooms","Ironing Facilities","Fire Place (wood)","LED TV with cable connection","Free WiFi access","Gas hob","Fridge &amp Microwave"]"
  ]
  2 => array:2 [▼
    "key" => "intro"
    "content" => """
      It is situated less than a kilometer from the centre of Ooty. It consists two number of three-bedroom and three number of two-bedroom cottages with common facilities.\n
      \n
      This is a luxury Cottage built to satisfy the discerning taste of a vacationer. The cottage is a wonderful establishment that is fully furnished with carefully selected interiors that blends seamlessly with modern scenery. Two Seas is not only a cozy place but also a house provided with all luxuries and convenience. Ideal for family holiday, a quiet get away for a couple or high profile guests.\n
      \n
      Open plan living room with kitchen and dining areas. The high ceiling, fire place (flame picture can be viewed from almost anywhere in the living room), paintings and decoration make the living room a lovely place to be. Well equipped kitchen with everything you need for self-catering with lovely views over hillside. Spacious bedrooms with king size beds, full size wardrobe, dressing table with vanity mirror, bedside tables and access to balconies. En-suite shower to all rooms with Italian designer sanitary ware with Toto accessories.
      """
  ]
  3 => array:2 [▼
    "key" => "banner"
    "content" => "http://content.twoseasresidence.com/wp-content/uploads/2015/08/front-wide-e1438797045904.jpg"
  ]
  4 => array:2 [▼
    "key" => "map"
    "content" => "http://dev.twoseasresidence.com/frontend/img/maps.png"
  ]
]

But I need to flatten the collection based on the value of the key and value of the content so that i can select an item like

$array['map'] or $collection->map //results http://dev.twoseasresidence.com/frontend/img/maps.png

Any ideas?

0 likes
7 replies
lancebutler2's avatar

Maybe you could leave Individuals as a collection, and use laravel's collection filter method.

$individuals = Individuals::wherePage('home')->get(['key','content'];

$map = $individuals->filter(function($item) {
    return $item->key == 'map';
})->first();  // used first() because filter will return a collection

return $map->content; // should be "http://dev.twoseasresidence.com/frontend/img/maps.png"
divanoli's avatar

Hi @lancebutler2 thanks for your reply. Your solution works. But I don't want to hardcode to get the results of all they keys. I just want to transform

array:5 [▼
  0 => array:2 [▼
    "key" => "title"
    "content" => "Two Seas Residence"
  ]
  1 => array:2 [▼
    "key" => "overview"
    "content" => "some overview"
  ]
  2 => array:2 [▼
    "key" => "intro"
    "content" => "some intro"
  ]
  3 => array:2 [▼
    "key" => "banner"
    "content" => "http://content.twoseasresidence.com/wp-content/uploads/2015/08/front-wide-e1438797045904.jpg"
  ]
  4 => array:2 [▼
    "key" => "map"
    "content" => "http://dev.twoseasresidence.com/frontend/img/maps.png"
  ]
]

into

array:1 [▼
  0 => array:5 [▼
    "title" => "Two Seas Residence"
    "intro" => "some intro"
    "overview" => "some overview"
    "banner" => "http://content.twoseasresidence.com/wp-content/uploads/2015/08/front-wide-e1438797045904.jpg"
    "map" => "http://dev.twoseasresidence.com/frontend/img/maps.png"    
  ]
]

Like this. So that i can get the content like

$collection->intro // some intro
$collection->overview // some overview
$collection->map // http://dev.twoseasresidence.com/frontend/img/maps.png
sylar's avatar

Ideas:

$flat = array[];
array_walk($array, function($el, $index) use (&$flat) {
    $flat[$el['key']] = $el['content'];
    return $flat;
});
OR
$flat = [];
foreach($array as $k => $v) {
  $flat[$v['key']] = $v['content'];
}

I think you can use $collection = $collection->each(function ($item, $key) {

});

and also check https://vimeo.com/115719437 Refactoring Loops and Conditionals from Adam Wathan

2 likes
Bloomanity's avatar
Level 22
collect($array)->pluck('content', 'key');
or
$collection->pluck('content', 'key');

try also

$individuals = Individuals::wherePage('home')->get(['key','content'])->pluck('content', 'key');
or
$individuals = Individuals::wherePage('home')->lists('content', 'key');

see if any work and tell us which one you used

3 likes
divanoli's avatar

I came with this solution

class IndividualsRepository
{
    protected $contentArray = [];
    public function getHomeContent() {
        $individuals = Individuals::wherePage('home')->get(['key','content']);

       $individuals->each(function($item,$key){
           $currentItem = $item->toArray();
           //var_dump($currentItem['key'],"=>".$currentItem['content']);
           $this->contentArray[$currentItem['key']] = $currentItem['content'];
           return true;
       });
        return ($this->contentArray);
    }
}

which results in

array:5 [▼
  "title" => "Two Seas Residence"
  "overview" => "some overview"
  "intro" => "some intro"
  "banner" => "http://content.twoseasresidence.com/wp-content/uploads/2015/08/front-wide-e1438797045904.jpg"
  "map" => "http://dev.twoseasresidence.com/frontend/img/maps.png"
]

I will check all your ideas too. Thanks for all your replies.

divanoli's avatar

@Bloomanity I think your idea is nice and simple. Works good. I didn't think of pluck usage before. I thought it will also return a collection of different arrays. Thanks for all your suggestions. @Bloomanity thanks again.

2 likes

Please or to participate in this conversation.