#1
  1. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171

    Difficult! Filter array based on key values. Is it possible?


    In the array below I need to filer and choose only 1 elements per hotel_id. The element with smallest value in key total.

    For example there are more than 1 element with [hotel_id] => 587 in the array below. [1] will be removed as the value for total is 1404 and the value for [0] (or [2]) gets selected as it is 1266.

    I thought I title this "Find element with minimum value for a key among all elements with same key."

    Can anyone help?

    PS. I can build the array any how that I want. Here I do:
    PHP Code:
                                    $hotels_selection[] = array('hotel_id'=>$get_package_res->HID,
     array(
    'total'=>$TOTAL,
     
    'available_rooms'=>$A_R
    'status'=>$status,
    'PID'=>$get_package_res->PPIIDD,
     
    'HID'=>$get_package_res->HID) ); 
    Thanks
    Code:
    
    [0] => Array
            (
                [hotel_id] => 587
                [0] => Array
                    (
                        [total] => 1266
                        [available_rooms] => 0
                        [status] => r
                        [PID] => 650
                        [HID] => 587
                    )
    
            )
    
        [1] => Array
            (
                [hotel_id] => 587
                [0] => Array
                    (
                        [total] => 1404
                        [available_rooms] => 0
                        [status] => r
                        [PID] => 651
                        [HID] => 587
                    )
    
            )
    
        [2] => Array
            (
                [hotel_id] => 587
                [0] => Array
                    (
                        [total] => 1266
                        [available_rooms] => 0
                        [status] => r
                        [PID] => 2333
                        [HID] => 587
                    )
    
            )
    
        [3] => Array
            (
                [hotel_id] => 490
                [0] => Array
                    (
                        [total] => 660
                        [available_rooms] => 0
                        [status] => r
                        [PID] => 608
                        [HID] => 490
                    )
    
            )
    
        [4] => Array
            (
                [hotel_id] => 490
                [0] => Array
                    (
                        [total] => 582
                        [available_rooms] => 0
                        [status] => r
                        [PID] => 609
                        [HID] => 490
                    )
    
            )
    Last edited by zxcvbnm; March 22nd, 2013 at 12:28 AM.
  2. #2
  3. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,295
    Rep Power
    9400
    You wouldn't happen to be getting this data from a database, would you?
  4. #3
  5. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    Originally Posted by requinix
    You wouldn't happen to be getting this data from a database, would you?
    Yes why?
  6. #4
  7. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    ? What happened?
  8. #5
  9. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,295
    Rep Power
    9400
    Nothing happened

    What's that query? There might be an easy way to get the data you actually want by making the database do the work.
  10. #6
  11. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    Originally Posted by requinix
    Nothing happened

    What's that query? There might be an easy way to get the data you actually want by making the database do the work.
    I tried with uncle Rudy. Got very close but I don't have enough knowledge to take that road at this stage. So I am playing with arrays here. Also very close
  12. #7
  13. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,295
    Rep Power
    9400
    Okay.

    Loop through the list, building up a new array as you go. Use the hotel_id as the key and the $hotels_selection's array key as the value. As you go through, check if the current hotel_id exists in the array: if so then compare the "total"s from the two and replace the value if the current one is greater, if not then just add it.
    PHP Code:
    $lookup = array();
    foreach (
    $hotels_selection as $key => $value) {
        if (isset(
    $lookup[$value["hotel_id"]])) {
            if (
    $hotels_selection[$lookup[$value["hotel_id"]]][0]["total"] < $value[0]["total"]) {
                
    $lookup[$value["hotel_id"]] = $key;
            }
        } else {
            
    $lookup[$value["hotel_id"]] = $key;
        }

    $lookup will then be an array of hotel_ids mapped to keys in $hotels_selection of the one with the greatest total.

    For bonus points:
    1. Realize that you could do this as you're pulling rows from the resultset - no need for a separate loop.
    2. The if block in the loop only ever really does one thing: set something in $lookup. You could just combine the two conditions and keep the one statement (the condition would look like (A && B) || C). I didn't because that stuff above looks crazy enough as it is, what with all the array keys and values.

    Speaking of crazy, if that looks too complicated then use a couple temporary variables to help you keep track. And feel free to print out stuff.
  14. #8
  15. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    Originally Posted by requinix
    Okay
    Look at that! That looks brilliant. I go have a play with it.

    Just out of curiosity, is this basic php?
  16. #9
  17. Transforming Moderator
    Devshed Supreme Being (6500+ posts)

    Join Date
    Mar 2007
    Location
    Washington, USA
    Posts
    14,295
    Rep Power
    9400
    "Basic PHP"? Not sure what you mean by that.
    I've seen this kind of problem many times before so I'm familiar with ways to solve it. That's actually true for the vast majority of questions I reply to here.
  18. #10
  19. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    Originally Posted by requinix
    "Basic PHP"? Not sure what you mean by that.
    Beginners level?
  20. #11
  21. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4124
    there's two ways to look at "basic" or "beginners"

    1) logic
    2) code function

    Here, the logic is quite basic. If you had the data on paper and wanted to do it manually, what would be your throught process? This has then been mapped to code in few lines. Also, the code here quite simple, we're just using a loop and an if/else.

    For something that will leave you wondering "WTF?" have a look at PHP5.5's generators RFC (link)
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  22. #12
  23. A Change of Season
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2004
    Location
    Next Door
    Posts
    2,688
    Rep Power
    171
    Originally Posted by requinix
    Okay.

    Loop through the list, building up a new array as you go. Use the hotel_id as the key and the $hotels_selection's array key as the value. As you go through, check if the current hotel_id exists in the array: if so then compare the "total"s from the two and replace the value if the current one is greater, if not then just add it.
    PHP Code:
    $lookup = array();
    foreach (
    $hotels_selection as $key => $value) {
        if (isset(
    $lookup[$value["hotel_id"]])) {
            if (
    $hotels_selection[$lookup[$value["hotel_id"]]][0]["total"] < $value[0]["total"]) {
                
    $lookup[$value["hotel_id"]] = $key;
            }
        } else {
            
    $lookup[$value["hotel_id"]] = $key;
        }

    $lookup will then be an array of hotel_ids mapped to keys in $hotels_selection of the one with the greatest total.
    Correct and it prints
    Code:
    Array ( [587] => 1 [490] => 3 [1958] => 6 [863] => 9 [177] => 10 [1168] => 16 [995] => 17 [996] => 18 [999] => 19 [1000] => 21 [1001] => 22 [1004] => 24 [1005] => 25 [1007] => 26 [1008] => 27 [1009] => 28 [1010] => 29 [1012] => 30 [682] => 31 [1636] => 33 [248] => 39 [1847] => 42 [401] => 44 [1175] => 48 [912] => 50 [913] => 54 [914] => 55 [915] => 58 [916] => 59 [918] => 60 [920] => 61 [330] => 62 [1105] => 64 [171] => 68 [1157] => 69 [164] => 76 [1179] => 77 [399] => 78 [367] => 86 [1162] => 87 [1860] => 97 [1177] => 100 [349] => 103 )
    But how can I access the rest of the data? I need the rest of the information from $hotels_selection as well. That includes: total, available_rooms, status and PID (All the values is this array below):
    PHP Code:
    $hotels_selection[] = array('hotel_id'=>$get_package_res->HID,
     array(
    'total'=>$TOTAL,
     
    'available_rooms'=>$A_R
    'status'=>$status,
    'PID'=>$get_package_res->PPIIDD,
     
    'HID'=>$get_package_res->HID) ); 
    So I changed your code to
    PHP Code:
     $lookup = array();
    foreach (
    $hotels_selection as $key => $value) {
        if (isset(
    $lookup[$value["hotel_id"]])) {
            if (
    $hotels_selection[$lookup[$value["hotel_id"]]][0]["total"] < $value[0]["total"]) {
                
    $lookup[$value["hotel_id"]] = $value;
            }
        } else {
            
    $lookup[$value["hotel_id"]] = $value;
        }

    And looks like I can access the right values this way:
    PHP Code:
    foreach($lookup as $val =>$row)
        {
            echo 
    $val.":<br />";
            
    print_r($row);
            echo 
    "<hr />";
        } 
    I am just a bit insecure about this thats why I am triple checking here. So is my solution the answer to my question? It looks like it's correct.

    Thanks
    Last edited by zxcvbnm; March 24th, 2013 at 11:32 PM.

IMN logo majestic logo threadwatch logo seochat tools logo