SitePoint Sponsor

User Tag List

Results 1 to 12 of 12

Thread: Sorting arrays

  1. #1
    SitePoint Member
    Join Date
    Jul 2004
    Location
    UK
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Sorting arrays

    Hi Guys,

    I have a little trouble and i'm in need of some help.

    I have an array that i have created and is layed out below. I think they call this multi dimensional.
    $entries[customerid][x_cord]
    $entries[customerid][y_cord]
    $entries[customerid][dist]

    The sample values are as follows:
    $entries[1][x] = 10
    $entries[1][y] = 50
    $entries[1][dist] = 60

    $entries[2][x] = 20
    $entries[2][y] = 20
    $entries[2][dist] = 40

    $entries[3][x] = 40
    $entries[3][y] = 10
    $entries[3][dist] = 50

    The out come i'm after is to sort this array on the [dist] part of the array so the lowset value is at the top of the array ie. the first row but i'm not sure how to achieve this.

    If you can help i'd be very greatful

    Thank in advance
    Matt

  2. #2
    SitePoint Wizard Sillysoft's Avatar
    Join Date
    May 2002
    Location
    United States :)
    Posts
    1,691
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

  3. #3
    SitePoint Wizard swdev's Avatar
    Join Date
    Oct 2004
    Location
    UK
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not sure if array_multisort will work - haven't tested it, but if it doesn't, try this code

    PHP Code:
     $entries[1]['x'] = 10;
     
    $entries[1]['y'] = 50;
     
    $entries[1]['dist'] = 60;
     
     
    $entries[2]['x'] = 20;
     
    $entries[2]['y'] = 20;
     
    $entries[2]['dist'] = 40;
     
     
    $entries[3]['x'] = 40;
     
    $entries[3]['y'] = 10;
     
    $entries[3]['dist'] = 50;
     
     function 
    cmp ($Array1$Array2)
     {
       return (
    $Array1['dist'] - $Array2['dist']);
     }
     
     
    usort($entries'cmp');
     
    print_r($entries); 

  4. #4
    eschew sesquipedalians silver trophy sweatje's Avatar
    Join Date
    Jun 2003
    Location
    Iowa, USA
    Posts
    3,749
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    or, to refine swdev's idea
    PHP Code:
       usort($entriescreate_function('$a,$b','return ($a["dist"]-$b["dist"]);')); 
    Jason Sweat ZCE - jsweat_php@yahoo.com
    Book: PHP Patterns
    Good Stuff: SimpleTest PHPUnit FireFox ADOdb YUI
    Detestable (adjective): software that isn't testable.

  5. #5
    SitePoint Member
    Join Date
    Jul 2004
    Location
    UK
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Red face

    I'm really sorry guys but i'm not getting this. I've had a little rethink though.

    This is what i've got. I have a table of tickets sold and they include the customerid and some x and y values. What i want to do is query the table and build an array where i get a key = to customerid and a value of the below calculation.

    $sum = sqrt(pow($xvalue) + pow($yvalue));

    so it should resemble something like this.

    Key Value
    $array[0001] = 12
    $array[0002] = 15
    $array[0003] = 20

    Then i just want to evaluate which one of these is closest to my winning value.

    $winner = 16

    I know how to do closest using a subtraction and it using abs() so they are all positive. Then i can work out the smallest difference.

    So the end result should be a result of customer id 0002 being the winner.

    If you can help i would be so greatful.

    Thanks guys, your comments have been great i'm just sorry i don't understand.

  6. #6
    SitePoint Wizard swdev's Avatar
    Join Date
    Oct 2004
    Location
    UK
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    The pow function takes 2 parameters.

    I'm not sure if this is what you want but try this code

    PHP Code:
     // Required winning value - change as required
     
    $winning_value 16;
     
     
    // Actual winning value - do not change
     
    $actual_winning_value = -1;
     
    // winning customer id - do not change
     
    $winning_id = -1
     
    // current difference between this guess and current winning guess - do not change
     
    $curr_diff 999999;
     
     
    $sql 'SELECT '
          
    ' customer_id, xvalue, yvalue'
          
    ' FROM'
          
    ' ticket_table'
          
    ;
     
     
    /* ***** START DIAGNOSTIC ***** */
     
    echo 'Executing ' $sql '<br />';
     
    /* ***** END DIAGNOSTIC ***** */
     
     
    $result mysql_query($sql) or die ('Failed to execute ' $sql ' due to ' mysql_error());
     
     while (
    $row mysql_fetch_assoc($result))
     {
       
    // calculate value
       
    $v sqrt pow(intval($row['xvalue']), 2) + pow(intval($row['yvalue']), 2) );
       
    // work out difference from real winning value
       
    $diff abs($v $winning_value);
       
    // if this is a closer guess
       
    if ($diff $curr_diff)
       {
         
    // save this data
         
    $curr_diff $diff;
         
    $winning_id $row['dustomer_id'];
         
    $actual_winning_value $v;
       }
     }
     
     
    // display winning information
     
    if (-== $winning_id)
     {
       echo 
    ' There were no winners<br />';
     }
     else
     {
       if (
    $actual_winning_value == $winning_value)
       {
         echo 
    'Winner is customer id ' .  $winning_id '<br />';
       }
       else
       {
         echo 
    ' Nearest winner is customer id ' $winning_id ' with a value of ' $actual_winning_value '<br />';
       }
     } 
    There is no need to invole an array except for the data returned from the database.

    Hope this helps

  7. #7
    SitePoint Member
    Join Date
    Jul 2004
    Location
    UK
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks swdev,
    That code looks great. Also, thank you for the comments too.
    I'll give this a go and let you know how i get on.

  8. #8
    SitePoint Wizard swdev's Avatar
    Join Date
    Oct 2004
    Location
    UK
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Thanks for the kind words. I hope it does the job

  9. #9
    SitePoint Member
    Join Date
    Jul 2004
    Location
    UK
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Another problem

    This code works great, it works out exactly as i want but i still have a problem.

    I used the <input type=image> html to pass through two co-ordinates but it looks like this might be wrong.

    This is the layout i have i think

    0 |
    |
    |
    |
    |
    |
    |
    100|_________________
    0 100

    I think this is the diagram i need.

    100|
    |
    |
    |
    |
    |
    |________________
    0 100

    My question is how do i get a image map using this axis instead of the top one. The top one screws my calculation that i use (As shown by swdev).

  10. #10
    SitePoint Wizard swdev's Avatar
    Join Date
    Oct 2004
    Location
    UK
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Not sure i fully understand what you are asking, but trying to remember my maths from way too many years ago ) ) you could replace the yvalue with -1 * the current yvalue
    e.g current_yvalue = 80, multiply it by -1 to get -80. The pow function will still give the same result.
    Try it and let us know if it works.

  11. #11
    SitePoint Member
    Join Date
    Jul 2004
    Location
    UK
    Posts
    19
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I'll try and explain a bit better.
    I'm not sure if this is the right way round or not but i'll use x as horizontal and y as vertical.

    What i want is the bottom left corner to be value 0 for both axis and the top of Y = to be the height in pixels of the image and the far right or X to be what ever the image pixel is. It should look like this. I'll use the value of 250 for each in this example.
    Graph 1
    250
    |
    |
    |
    |
    |
    |
    0-----------------250

    instead using the <input> tag uses this layout.

    Graph 2
    0
    |
    |
    |
    |
    |
    |
    250
    |0----------------250

    This means that if i use your code from above and you have the following positions using the second graph i get the wrong winner.

    Winner = 200 x 50
    User1 = 20 x 230
    User2 = 230 x 20

    The final value using the pow() and sqrt() calculation you get

    Winner = 206.15528128088
    User1 = 230.8679276123
    User2 = 230.8679276123

    As you can see User1 and User2 have the same values. This is right using graph 2 but if you've drawn this you'll see that user 2 is the actual winner. This leads me to the conclusion i need graph 1 to make this work but there must be a sum i can do to make graph 2 work as i can't change how the X and Y's are setup.

    Sorry for this being so long but just trying to make this clear, i hope this has helped.

  12. #12
    SitePoint Wizard swdev's Avatar
    Join Date
    Oct 2004
    Location
    UK
    Posts
    1,053
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ok - I think I follow what you want.

    You need to replace the yvalue with yvalue - maxyvalue

    In your example, max_yvalue = 250

    So
    Original Data

    Winner = 200 x 50
    User1 = 20 x 230
    User2 = 230 x 20

    becomes
    Winner = 200 x (50 - 250) = 200 x -200 = 282.84271247
    User1 = 20 x (230 - 250) = 20 x -20 = 28.284271247
    User2 = 230 x (20 - 250) = 20 x -230 = 230.86792761

    hence User2 is the winner!

    Essentially, from a graphical point of view, you are moving the displacing the y axis.

    hope this helps


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
  •