0

I'm creating a recent activity section and I am trying to group similar items. I want to be able to group activities based on type of activity and who did the activity. For instance:

Array
(
    [0] => Array
        (
            [user] => Bill
            [type] => photo
            [id] => 1
            [timestamp] => 12345678
        )

    [1] => Array
        (
            [user] => Joe
            [type] => photo
            [id] => 2
            [timestamp] => 12345678
        )

    [2] => Array
        (
            [user] => Bill
            [type] => comment
            [id] => 1
            [timestamp] => 12345678
        )

    [3] => Array
        (
            [user] => Bill
            [type] => photo
            [id] => 3
            [timestamp] => 12345678
        )

)

could turn into this:

Array
(
    [0] => Array
        (
            [user] => Bill
            [type] => photo
            [items] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [timestamp] => 12345678
                        )

                    [1] => Array
                        (
                            [id] => 3
                            [timestamp] => 12345678
                        )

                )

        )

    [1] => Array
        (
            [user] => Joe
            [type] => photo
            [items] => Array
                (
                    [0] => Array
                        (
                            [id] => 2
                            [timestamp] => 12345678
                        )

                )

        )

    [2] => Array
        (
            [user] => Bill
            [type] => comment
            [items] => Array
                (
                    [0] => Array
                        (
                            [id] => 1
                            [timestamp] => 12345678
                        )

                )

        )

)

This is almost what I am trying to do but not quite there: Grouping arrays in PHP

Anyone have an idea?

Community
  • 1
  • 1
nlyn
  • 606
  • 1
  • 7
  • 20

2 Answers2

1

Your grouping doesn't exactly make sense (it makes a little more sense after your edit), try this:

foreach ($activity as $data) {
   $newdata[$data['user']][$data['type']]['id'][]=$data['id'];
   $newdata[$data['user']][$data['type']]['timestamp'][]=$data['timestamp'];
}

Edit to reflect your changes in desired output: (and a structure that is a bit more useful)

foreach ($activity as $data) {
    $newdata[$data['user']][$data['type']]['items'][]=array('id'=>$data['id'],'timestamp'=>$data['timestamp']);
}  

Edit 2:

You have to have some sort of key, in this case its a combo of the username and the type. Then you have to re-index it so its numeric if that actually matters. That should be quite close to exactly what you want:

foreach ($activity as $data) {
        $key=$data['user'].'-'.$data['type'];
        $newdata[$key]['items'][]=array('id'=>$data['id'],'timestamp'=>$data['timestamp']);
        $newdata[$key]['user']=$data['user'];
        $newdata[$key]['type']=$data['type'];
}
$newdata=array_values($newdata);

tested:
http://www.ideone.com/3uZdd

Edit 3:

separate dates... this is the idea to get you started, you'll need to do a little more to the original array for this.

foreach ($activity as $data) {
        $key=$data['user'].'-'.$data['type'];
        $newdata[$key]['items'][$data['day']][]=array('id'=>$data['id'],'timestamp'=>$data['timestamp']);
        $newdata[$key]['user']=$data['user'];
        $newdata[$key]['type']=$data['type'];
}
$newdata=array_values($newdata);
profitphp
  • 8,104
  • 2
  • 28
  • 21
  • that's looking pretty good thanks. but it would be better for me to have each outputted action (after the grouping) to not be a child of it's user - basically more like my example. – nlyn Jul 20 '11 at 22:33
  • it will be output something like: * Bill added 2 Photos * Joe added photo number 1 * Bill wrote comment number 1 – nlyn Jul 20 '11 at 22:49
  • @ndog updated again. Your data structure still doesn't make sense, but that's should do what you want. – profitphp Jul 20 '11 at 22:53
  • @ndog my last update had some issues, sorry, fixed now, tested, works just how you wanted it – profitphp Jul 20 '11 at 23:06
  • That looks awesome... now, what if I was to add another level of complexity to this... Only grouping activities in 24 hour blocks. So if Bill added a photo last week, then 2 today. todays would be grouped together and last weeks would be on it's own? – nlyn Jul 20 '11 at 23:11
  • @ndog ill make another edit. dont forget to accept answer, and upvote. – profitphp Jul 20 '11 at 23:18
  • that's pretty close, though not quite what I was thinking. I mean for actions to be grouped within the last 24 hours - not the day of the week. I guess this will add a bit more complexity to the thing :P – nlyn Jul 21 '11 at 09:28
  • @ndog, ya pretty much. Ive given you what you originally asked for, and you should be able to figure it out from here. So you should accept and vote. To do what you want, when you're making the original array, check if its from today, then make `$a['day']='today'` and if its from earlier make `$a['day']='past'` – profitphp Jul 21 '11 at 16:01
  • didn't have enough rep points to vote up - but I accepted. thanks a lot for the help, you've actually been a bit of a life saver! – nlyn Jul 21 '11 at 16:38
0

Try using uasort with a custom function that sorts on the values of user and type.

Jonathan M
  • 17,145
  • 9
  • 58
  • 91