22

I have a php object (book) with 3 properties: name, category, description I then have a list of these book objects in an array. I want to create a new associative array for these objects grouped by category.

Say I have 4 book objects in an array called $books

name    category  description
==================================
book1   cat1     this is book 1
book2   cat1     this is book 2
book3   cat2     this is book 3
book4   cat3     this is book 4

how can I create an associative array called $categories

$categories['cat1'] = array(book1, book2)
$categories['cat2'] = array(book2)
$categories['cat3'] = array(book3)

where book? is the book object and not the word

8 Answers 8

64

Like this:

foreach($books as $book)
{ 
    $categories[$book->category][] = $book;
}
Sign up to request clarification or add additional context in comments.

2 Comments

If you've found this answer and aren't immediately aware of what it's doing -- it's creating a new array (named $categories) with a key for every value of $book->category. Each key's value is an array of $book objects that correspond to that $book->category. I'd make an ASCII picture if it wouldn't look like mud in this comment.
And if you want to sort the categories, that's extra: ksort($categories); See php.net/manual/en/function.ksort.php
5

Simply loop the array of objects into a new array with the key being the category:

$newArray = array();
foreach($array as $entity)
{
    if(!isset($newArray[$entity->category]))
    {
         $newArray[$entity->category] = array();
    }

    $newArray[$entity->category][] = $entity;
}

Is this what you was looking for ?

Explanation of the code:

/*
    * Create a new blank array, to store the organized data in.
*/
$newArray = array();

/*
    * Start looping your original dataset
*/
foreach($array as $entity)
{

    /*
        * If the key in the new array does not exists, set it to a blank array.
    */
    if(!isset($newArray[$entity->category]))
    {
         $newArray[$entity->category] = array();
    }

    /*
        * Add a new item to the array, making shore it falls into the correct category / key
    */
    $newArray[$entity->category][] = $entity;
}

Comments

4

You can do it with ouzo goodies:

 $categories = Arrays::groupBy($books, Functions::extractField('category'));

See: http://ouzo.readthedocs.org/en/latest/utils/arrays.html#groupby

Comments

1
$categories = array();

for ($i = 0; $i < count($books); $i++){
    if (isset($categories[$books[$i]->category]) == false)
        $categories[$books[$i]->category] = array();

    $categories[$books[$i]->category][] = $books[$i]
}

cheers

Comments

0

Try this:

$categories = array();
foreach ($books as $book){

  if (!array_key_exists($book->category , $categories))
     $categories[$book->category] = array();

  $categories[$book->category][] = $book;

}

Comments

0

This should works:

$categories = array();
foreach ($books as $book) {

    $categories[$book['category']][] = $book;

}

1 Comment

Unlike JavaScript, you cannot access object properties with the array [propertyName] syntax.
0

I had a similar problem, but a bit more complicated with wordpress and metavalues/metakeys (where $results was an array of associative arrays fetched from a $wpdb->get_results() query.

This was my solution adapted to your problem:

$categories = array();
foreach ($results as $row) {
    $id =  $row['category'];
    $description = $row['category'];
    $name = $row['name']
    if (!isset($categories[$id])) {
        $categories[$id] = array();
    }
    $categories[$id] = array_merge($categories[$id], 'description'=>$description , 'name'=>$name);
}

Then you can run another for loop to get each array from the categories array:

foreach ($categories as $category) {
    var_dump($category);
}

Comments

0

If you want to group objects by getting key from specific method with or without additional arguments, you can use this library method:

Arr::groupObjects(array $objects, string $method, ...$args): array

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.