SitePoint Sponsor

User Tag List

Results 1 to 12 of 12

Hybrid View

  1. #1
    SitePoint Addict
    Join Date
    Jul 2007
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    How do I count and sort simple multidimensional array like this?

    Greetings,

    I have an array like this:

    Code:
    Array
    (
    [0] => Array
    (
    [userid] => 1
    [name] => Joe1
    )
    
    [1] => Array
    (
    [userid] => 1
    [name] => Joe1
    )
    
    [2] => Array
    (
    [userid] => 2
    [name] => Joe2
    )
    
    [3] => Array
    (
    [userid] => 3
    [name] => Joe3
    )
    
    [4] => Array
    (
    [userid] => 2
    [name] => Joe2
    )
    
    [5] => Array
    (
    [userid] => 2
    [name] => Joe2
    )
    
    )
    The userid corresponds to a name. I would like to count up how many times the userid appears in the array. Then I would like to sort the array where the userid with the highest count appears first and desends. Basically this is what I want the array to look like:

    Code:
    Array
    (
    [0] => Array
    (
    [userid] => 2
    [name] => Joe2
    [count] => 3
    )
    
    [1] => Array
    (
    [userid] => 1
    [name] => Joe1
    [count] => 2
    )
    
    [2] => Array
    (
    [userid] => 3
    [name] => Joe3
    [count] => 1
    )
    
    )
    Let me know how this can be done.

    Thanks
    Last edited by AnthonySterling; May 26, 2011 at 01:13.

  2. #2
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    I would use the userid as an array key, and walk the first array, adding to the new array's counters.

  3. #3
    SitePoint Addict
    Join Date
    Jul 2007
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Greetings StarLion,

    I'm not too experienced when it comes to arrays or array keys, this is the first time I've messed around with arrays in PHP. Could you provide some sample code on how to do this or if you know the complete code to do this?

    Thanks

  4. #4
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    Well lets see if you can take a stab yourself first.

    You will need:
    foreach
    Probably isset
    Always helps to brush up on your operators (note the Unary Increment operator)
    and for giggles array definitions.

  5. #5
    SitePoint Wizard
    Join Date
    Dec 2003
    Location
    USA
    Posts
    2,582
    Mentioned
    29 Post(s)
    Tagged
    0 Thread(s)
    If you get stuck, don't be afraid to ask further questions. StarLion isn't trying to be mean, he really is trying to help. =p

    Here is another hint: you'll probably have to step through each element in the first array and construct a new array for the results.

  6. #6
    I solve practical problems. bronze trophy
    Michael Morris's Avatar
    Join Date
    Jan 2008
    Location
    Knoxville TN
    Posts
    2,053
    Mentioned
    66 Post(s)
    Tagged
    0 Thread(s)
    array_multisort, though that array looks like a database result set. If it is you're better served using the ORDER BY clause of the query to sort the results before the dB hands them over to PHP - this will be MUCH faster.

    EDIT: Didn't spot the counting, but it's still a SQL problem

    Code sql:
    SELECT userid, COUNT(userid) AS `count`, name
    FROM myTable
    GROUP BY userid

    This will be enormously faster than any PHP solution you can devise (presuming of course a database is the true source of the array).

  7. #7
    SitePoint Addict
    Join Date
    Jul 2007
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I actually tried array_count_values() on a one dimensional array and it worked almost perfectly except it didn't sort the highest count first and descend. Unfortunately, I can't seem to get this working on a multidimensional array though. I've been trying to solve this for a few days now.

    I was going to try the "foreach" loop but I still need to wrap my head around a system of doing this and then creating the new array. I will keep trying until someone else can figure it out.

    Also, I've stored data results in my own array from a long series of independent SQL statements and loops that execute on the page, kind of like a count that records the userid and username whenever it shows up in the various loops. Then I want to show a grand total of sorts like above.

  8. #8
    SitePoint Addict
    Join Date
    Jul 2007
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    This is what I have so far, I've made the userid from the original array the array key:
    PHP Code:
    $newarray = array();
    foreach (
    $array as $key=>$value) {
       if(
    $key == $newarray[$key]['userid']) {
           
    $newarray[$key]['count'] = $newarray[$key]['count'] + 1;
       }
       else {
           
    $newarray[$key] = array("userid" => $value['userid'], "name" => $value['name'], "count" => 1);
       }

    It seems very close to working, the new array removes the duplicate user ids but it does not add to the count to reflect how many duplicates were found in the original array. I'm sure there is something simple, let me know what may be wrong.

    Thanks

  9. #9
    Twitter: @AnthonySterling silver trophy AnthonySterling's Avatar
    Join Date
    Apr 2008
    Location
    North-East, UK.
    Posts
    6,111
    Mentioned
    3 Post(s)
    Tagged
    0 Thread(s)
    PHP Code:
    <?php
    $users 
    = array(
      array(
    'id'  => 1'name'  => 'Bill'),
      array(
    'id'  => 2'name'  => 'Bob'),
      array(
    'id'  => 2'name'  => 'Bob'),
      array(
    'id'  => 1'name'  => 'Bill'),
      array(
    'id'  => 2'name'  => 'Bob'),
      array(
    'id'  => 1'name'  => 'Bill'),
      array(
    'id'  => 1'name'  => 'Bill'),
    );

    function 
    aggregate($users){
      
    $aggregated = array();
      foreach(
    $users as $user){
        if(!
    array_key_exists($user['id'], $aggregated)){
          
    $aggregated[$user['id']] = $user;
          
    $aggregated[$user['id']]['count'] = 0;
        }
        
    $aggregated[$user['id']]['count']++;
      }
      return 
    $aggregated;
    }

    function 
    sortByCount($a$b){
      
    $a $a['count'];
      
    $b $b['count'];
      if(
    $a === $b){
        return 
    0;
      }
      return 
    $a $b : -;
    }

    $users aggregate($users);

    usort($users'sortByCount');

    print_r($users);

    /*
      Array
      (
        [0] => Array
        (
          [id] => 1
          [name] => Bill
          [count] => 4
        )
        
        [1] => Array
        (
          [id] => 2
          [name] => Bob
          [count] => 3
        )
      )
    */
    You haven't clarified as to whether this data comes from a database though, if it does, you should use that to sort/group.
    @AnthonySterling: I'm a PHP developer, a consultant for oopnorth.com and the organiser of @phpne, a PHP User Group covering the North-East of England.

  10. #10
    SitePoint Wizard silver trophybronze trophy Cups's Avatar
    Join Date
    Oct 2006
    Location
    France, deep rural.
    Posts
    6,869
    Mentioned
    17 Post(s)
    Tagged
    1 Thread(s)
    Off Topic:

    hint: when posting array samples on which you would like help, use
    PHP Code:
    $s var_export$your_array);
    echo 
    $s
    instead of var_dump(), which means we have to type it all out again, which is time consuming, which... well, you get the idea.

  11. #11
    Keeper of the SFL StarLion's Avatar
    Join Date
    Feb 2006
    Location
    Atlanta, GA, USA
    Posts
    3,748
    Mentioned
    73 Post(s)
    Tagged
    0 Thread(s)
    As Michael and Anthony pointed out, if it's a DB result, consider using the query refinement suggested;

    You were indeed very close on your attempt. Anthony's code is pretty much what i'd do (I suggested you look at isset, he used array_key_exists, which takes the place of where i'd have used isset)

  12. #12
    SitePoint Addict
    Join Date
    Jul 2007
    Posts
    233
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks a lot Anthony, this really did the trick. I will continue studying this as I may need to take it a step further.

    The data actually comes from Facebook's FQL database. I'm learning how to build facebook apps so I can add it to my resume and improve my chances of finally getting a job! (I hope I don't have to become as brilliant as Anthony to get a decent PHP job) I've done some good stuff with PHP/MySQL but FQL and arrays are things I haven't worked with very often so this is great practice.


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •