3

I am trying to sort the mysql data by my calculated value. I know rsort(), sort(), however, I cannot sort them individual outside the foreach because it will not be consistent. I have three arrays need to be in consistent when I only want to sort them by the percentage. How can I do that? Appreciate.

<?php
   //certain mysql connection code hide because it's not relative to this question.
     foreach ($rows as row) {
    $member_id=row['user_id'];
    $count=row['count'];

    $user_link[]=bp_core_get_user_domain( $member_id );
    $user_displayname[]=bp_core_get_user_displayname( $member_id );

    $combine_count[]=round(($count/$count_user_diff)*100);//calculate value

   }//foreach
   //how can I sort data here since I have three arrays together.
for ($i=0; $i<7; $i++){
echo "<a href='$user_link[$i]'><div>$user_avatar[$i]<ul>$combine_count[$i]</ul></div></a>";
}

?>
1
  • Sort the first, get the list of keys from that, then use array_multisort() to sort the other two arrays based on that set of keys Commented Mar 6, 2015 at 17:49

2 Answers 2

2

One way to maintain a connection between the three array is to use associative arrays. If the member id is unique, then use it for the index of each array. For example:

<?php

  // $unique_id = 0; // in case $member_id is not unique
  foreach ($rows as $row) {
    $member_id = $row['user_id'];
    $count = $row['count'];

    // use $member_id as index to align arrays
    $user_link[$member_id]=bp_core_get_user_domain( $member_id );
    $user_displayname[$member_id]=bp_core_get_user_displayname( $member_id );
    //$user_avatar[$member_id]=bp_core_get_user_avatar( $member_id ); // missing avatar array?

    $combine_count[$member_id]=round(($count/$count_user_diff)*100);
    //$unique_id++;
  }

  arsort($combine_count); // maintain index, descending order
  // $combine_count = array_slice($combine_count, 0, 7, true); // top 7
  // slice array if you only want the top 7 as the question implies

  // loop over $combine_count array
  foreach ( $combine_count as $member_id => $c_count ) {
    echo "<a href='$user_link[$member_id]'><div>$user_avatar[$member_id]<ul>$combine_count[$member_id]</ul></div></a>";
  }

?>

If the member id's can occur multiple times in the result set, then simply instantiate a variable, such as $unique_id in the example, and increment it with each result, and use that for the index on all three arrays instead of $member_id.

Alternatively, if you want to show only the first few results, and you want to maintain the complete $combine_count array for later use, you can also do this:

arsort($combine_count); // maintain index, descending order

// loop over $combine_count array
$cc = 0; // start counter
foreach ( $combine_count as $member_id => $c_count ) {
  echo "<a href='$user_link[$member_id]'><div>$user_avatar[$member_id]<ul>$combine_count[$member_id]</ul></div></a>";
  $cc++; // increment counter
  if ( 7 <= $cc ) { break; } // break out of loop if counter is greater than or equal to 7
}

Are you missing some $s in your code, particularly row? I added where I thought they were missing. And it looks like you're missing the $user_avatar array. Or am I missing something?

Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much. Yes, when I paste the code, I might miss those. Although I not quite understand the unique ID part, how magical the member_id inside the array could achieve what I need, it works as I expect. Thanks again. But the slice array didn't work, I don't why. It slice 7 parts. 7 div, but only three div shows data, I fix this part by place a limit in the statement part, but just want to know why slice array doesn't work.Thanks again
You're welcome. I'm glad you pointed out the problem with array_slice. I failed to include the necessary "maintain index" flag as the last parameter to the function. I fixed the example above, and now it slices properly!
1

Why do you even use three separate arrays? Create one array, which has an associative structure with your three values. Then use usaort to sort your values in whatever order you like.

So, instead of

$user_link[]=bp_core_get_user_domain( $member_id );
$user_displayname[]=bp_core_get_user_displayname( $member_id );

$combine_count[]=round(($count/$count_user_diff)*100);//calculate value

you use

$data[] = array(
            'user_link' => bp_core_get_user_domain( $member_id ),
            'user_displayname' => bp_core_get_user_displayname( $member_id ),
            'combine_count' => round(($count/$count_user_diff)*100)
        );

Then use uasort on the $data. Bonus points if you create a custom Class instead of my associative array.

OR, even a better option: perform everything (calculations, sorting) in your database.

The proof-of-concept code:

<pre>
<?php

$data = array();

// Dummy entries
$data[] = array(
    'user_link' => '#',
    'user_displayname' => "Name",
    'combine_count' => 10
);

$data[] = array(
    'user_link' => '#',
    'user_displayname' => "Name",
    'combine_count' => 100
);

$data[] = array(
    'user_link' => '#',
    'user_displayname' => "Name",
    'combine_count' => 40
);

$data[] = array(
    'user_link' => '#',
    'user_displayname' => "Name",
    'combine_count' => 1000
);

// Comparator function
function compare($a, $b) {
    if($a == $b) {
        return 0;
    } else {
        return $a['combine_count'] < $b['combine_count'];
    }
}

// Print (before sorting)
print_r($data);

// Sort
uasort($data, 'compare');

// Print (after sorting)
print_r($data);

?>
</pre>

2 Comments

Thanks for you time. But I am not quiet understand how to separate the user_link from the $data[] and use uasort. If you could provide a example, that would be great. Anyway, still appreciate your help.
OK, I've updated my answer and provided a proof-of-concept code. Hope it is clear enough.

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.