Dr.Neo
Dr.Neo

Reputation: 1280

combine array values in sub array?

When I retrieve articles information from a mysql database I got an array like this:

Array
(
    [0] => Array
        (
            [CategoryID] => 3
            [CategoryName] => Test Category
            [Parent] => 0
            [Thumb] => 0
            [sort] => 8
            [ArticleID] => 2
            [ArticleCatgories] => 9,4,3
            [ArticleTitle] => vxcvxcvx
            [ArticleBody] => xcvxcvxcvxcv
            [InGroup] => 0
            [GroupID] => 0
            [Published] => 1
            [PublishTime] => 
            [TermID] => 11
            [TermSlug] => xcvxcvxcv
            [RelatedID] => 2
            [TermType] => article
        )

    [1] => Array
        (
            [CategoryID] => 4
            [CategoryName] => Test Image
            [Parent] => 0
            [Thumb] => 0
            [sort] => 4
            [ArticleID] => 2
            [ArticleCatgories] => 9,4,3
            [ArticleTitle] => vxcvxcvx
            [ArticleBody] => xcvxcvxcvxcv
            [InGroup] => 0
            [GroupID] => 0
            [Published] => 1
            [PublishTime] => 
            [TermID] => 11
            [TermSlug] => xcvxcvxcv
            [RelatedID] => 2
            [TermType] => article
        )

    [2] => Array
        (
            [CategoryID] => 9
            [CategoryName] => Test Images
            [Parent] => 0
            [Thumb] => 7
            [sort] => 2
            [ArticleID] => 2
            [ArticleCatgories] => 9,4,3
            [ArticleTitle] => vxcvxcvx
            [ArticleBody] => xcvxcvxcvxcv
            [InGroup] => 0
            [GroupID] => 0
            [Published] => 1
            [PublishTime] => 
            [TermID] => 11
            [TermSlug] => xcvxcvxcv
            [RelatedID] => 2
            [TermType] => article
        )
} 

And because the article is in more than one category, it retrieve the article information more than once. What I need to do is to combine the category names into a sub array if they have the same ArticleID so the result become like:

Array
(
    [0] => Array
        (
            [CategoryName] => array('Test Category','Test Image','Test Images');
            [Parent] => 0
            [Thumb] => 0
            [sort] => 8
            [ArticleID] => 2
            [ArticleCatgories] => 9,4,3
            [ArticleTitle] => vxcvxcvx
            [ArticleBody] => xcvxcvxcvxcv
            [InGroup] => 0
            [GroupID] => 0
            [Published] => 1
            [PublishTime] => 
            [TermID] => 11
            [TermSlug] => xcvxcvxcv
            [RelatedID] => 2
            [TermType] => article
        )
}

Upvotes: 1

Views: 2480

Answers (3)

Baba
Baba

Reputation: 95121

You can use array_reduce

$array = Array(
    "0" => Array("CategoryID" => 3,"CategoryName" => "Test Category","Parent" => 0,"Thumb" => 0,"sort" => 8,"ArticleID" => 2,"ArticleCatgories" => "9,4,3","ArticleTitle" => "vxcvxcvx","ArticleBody" => "xcvxcvxcvxcv","InGroup" => 0,"GroupID" => 0,"Published" => 1,"PublishTime" => null,"TermID" => 11,"TermSlug" => "xcvxcvxcv","RelatedID" => 2,"TermType" => "article"),
    "1" => Array("CategoryID" => 4,"CategoryName" => "Test Image","Parent" => 0,"Thumb" => 0,"sort" => 4,"ArticleID" => 3,"ArticleCatgories" => "9,4,3","ArticleTitle" => "vxcvxcvx","ArticleBody" => "xcvxcvxcvxcv","InGroup" => 0,"GroupID" => 0,"Published" => 1,"PublishTime" => null,"TermID" => 11,"TermSlug" => "xcvxcvxcv","RelatedID" => 2,"TermType" => "article"),
    "2" => Array("CategoryID" => 9,"CategoryName" => "Test Images","Parent" => 0,"Thumb" => 7,"sort" => 2,"ArticleID" => 2,"ArticleCatgories" => "9,4,3","ArticleTitle" => "vxcvxcvx","ArticleBody" => "xcvxcvxcvxcv","InGroup" => 0,"GroupID" => 0,"Published" => 1,"PublishTime" => null,"TermID" => 11,"TermSlug" => "xcvxcvxcv","RelatedID" => 2,"TermType" => "article"),
    "3" => Array("CategoryID" => 4,"CategoryName" => "Test A","Parent" => 0,"Thumb" => 0,"sort" => 4,"ArticleID" => 3,"ArticleCatgories" => "9,4,3","ArticleTitle" => "vxcvxcvx","ArticleBody" => "xcvxcvxcvxcv","InGroup" => 0,"GroupID" => 0,"Published" => 1,"PublishTime" => null,"TermID" => 11,"TermSlug" => "xcvxcvxcv","RelatedID" => 2,"TermType" => "article"),
    "4" => Array("CategoryID" => 9,"CategoryName" => "Test B","Parent" => 0,"Thumb" => 7,"sort" => 2,"ArticleID" => 2,"ArticleCatgories" => "9,4,3","ArticleTitle" => "vxcvxcvx","ArticleBody" => "xcvxcvxcvxcv","InGroup" => 0,"GroupID" => 0,"Published" => 1,"PublishTime" => null,"TermID" => 11,"TermSlug" => "xcvxcvxcv","RelatedID" => 2,"TermType" => "article")
);

$array = array_reduce($array, function ($a, $b) {
    is_null($a) ? $a = array() : null;
    if (!isset($a[$b['ArticleID']])) {
        $a[$b['ArticleID']] = $b ;
        $a[$b['ArticleID']]['CategoryName'] = array($b['CategoryName']);
    } else {
        $a[$b['ArticleID']]['CategoryName'][] = $b['CategoryName'];
    }
    return $a;
});

var_dump($array);

Output

array
  2 => 
    array
      'CategoryID' => int 3
      'CategoryName' => 
        array
          0 => string 'Test Category' (length=13)
          1 => string 'Test Images' (length=11)
          2 => string 'Test B' (length=6)
      'Parent' => int 0
      'Thumb' => int 0
      'sort' => int 8
      'ArticleID' => int 2
      'ArticleCatgories' => string '9,4,3' (length=5)
      'ArticleTitle' => string 'vxcvxcvx' (length=8)
      'ArticleBody' => string 'xcvxcvxcvxcv' (length=12)
      'InGroup' => int 0
      'GroupID' => int 0
      'Published' => int 1
      'PublishTime' => null
      'TermID' => int 11
      'TermSlug' => string 'xcvxcvxcv' (length=9)
      'RelatedID' => int 2
      'TermType' => string 'article' (length=7)
  3 => 
    array
      'CategoryID' => int 4
      'CategoryName' => 
        array
          0 => string 'Test Image' (length=10)
          1 => string 'Test A' (length=6)
      'Parent' => int 0
      'Thumb' => int 0
      'sort' => int 4
      'ArticleID' => int 3
      'ArticleCatgories' => string '9,4,3' (length=5)
      'ArticleTitle' => string 'vxcvxcvx' (length=8)
      'ArticleBody' => string 'xcvxcvxcvxcv' (length=12)
      'InGroup' => int 0
      'GroupID' => int 0
      'Published' => int 1
      'PublishTime' => null
      'TermID' => int 11
      'TermSlug' => string 'xcvxcvxcv' (length=9)
      'RelatedID' => int 2
      'TermType' => string 'article' (length=7)

Upvotes: 1

Ja͢ck
Ja͢ck

Reputation: 173572

You can build a new array using ArticleID as the keys:

$final = array();
foreach ($rows as $row) {
    $id = $row['ArticleID'];
    if (isset($final[$id])) {
        // we've already seen this article
        // append to categoryname array
        $final[$id]['CategoryName'][] = $row['CategoryName'];
    } else {
        // this is the first article occurrence
        // turn categoryname into array first
        $row['CategoryName'] = array($row['CategoryName']);
        $final[$id] = $row;
    }
}

print_r($final);

Output based on your question:

Array
(
    [2] => Array
        (
            [CategoryID] => 3
            [CategoryName] => Array
                (
                    [0] => Test Category
                    [1] => Test Image
                    [2] => Test Images
                )

            [Parent] => 0
            [Thumb] => 0
            [sort] => 8
            [ArticleID] => 2
            [ArticleCatgories] => 9,4,3
            [ArticleTitle] => vxcvxcvx
            [ArticleBody] => xcvxcvxcvxcv
            [InGroup] => 0
            [GroupID] => 0
            [Published] => 1
            [PublishTime] =>
            [TermID] => 11
            [TermSlug] => xcvxcvxcv
            [RelatedID] => 2
            [TermType] => article
        )

)

Upvotes: 1

Kartik
Kartik

Reputation: 9853

This is really a quick and dirty way of doing it but this is how it goes:

$orig is the original array posed in the question.

You basically iter the array and get all the categories and add them to $keys. Now assuming that all the other keys and values are same for the original array (except that category of course), you can just pick any element from that array and call it your $final array.

After that, you simply replace the category values with the array of the combined categories.

$orig = array();

$final = array();
$keys = array();

foreach($orig as $i)
{
    $keys[] = $i['CategoryName'];
}

$final = $orig[0];
$final['CategoryName'] = $keys;

Upvotes: -1

Related Questions