#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0

    Unhappy Array_pop to trim array to specified size - not working


    So, here is my code:

    PHP Code:
    $array = array(1,2,3,4,5,6,7,8,9);
    $desiredArraySize 3;

    if(
    count($array) > $desiredArraySize) {
        for(
    $i 0$i count($array) - $desiredArraySize$i++){
            
    array_pop($array);
        }

    What I wan to do is: take an array ($array) and remove the last element of that array n-times until the size of the array is as desired - the $desiredArraySize.

    My code just doesn't seem to be working and I wasn't sure why. Any ideas?

    Oh...and $array is not the real name of the array variable; it just makes more sense using it when explaining my issue.
  2. #2
  3. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Hi,

    I know of no error saying "doesn't work". My PHP doesn't have that. Could you try describing the concret issue?

    I guess your problem is that the array is longer than the desired size. That's because you recalculate the superfluous elements on each iteration. You need to do that before the loop.

    In any case, this is by far the most cumbersome and inefficient way of truncating an array. Why not use array_slice?
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Originally Posted by Jacques1
    Hi,

    I know of no error saying "doesn't work". My PHP doesn't have that. Could you try describing the concret issue?

    I guess your problem is that the array is longer than the desired size. That's because you recalculate the superfluous elements on each iteration. You need to do that before the loop.

    In any case, this is by far the most cumbersome and inefficient way of truncating an array. Why not use <Edited out>?
    Well if I use an array of length 9, and a desired array length of 3, I end up with the original array as length 6.

    With array_slice, the array indexes aren't necessarily numerical so I can't specify an offset I don't think.

    Hmm...this seems to work:

    PHP Code:
    if($numEvents != && count($events) > $numEvents) {
        while(
    count($events) != $numEvents) {
            
    array_pop($events);
        }

  6. #4
  7. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    Truncating an associative array to a specific length is kind of nonsensical, because conceptually, hashes have no order.

    Sure, you can do that in PHP, because the "arrays" in PHP are a weird mishmash of arrays, hashes, stacks, queues etc. But this is still very confusing, especially when this isn't just your personal project and other people might work on it.

    When I define an associative array, I don't expect it to make a difference whether I say
    PHP Code:
    array(
        
    'Justin' => 'Bieber'
        
    'Lady' => 'Gaga'

    or
    PHP Code:
    array(
        
    'Lady' => 'Gaga'
        
    'Justin' => 'Bieber'

    Your code will break that intuition.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  8. #5
  9. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Originally Posted by Jacques1
    Truncating an associative array to a specific length is kind of nonsensical, because conceptually, hashes have no order.

    Sure, you can do that in PHP, because the "arrays" in PHP are a weird mishmash of arrays, hashes, stacks, queues etc. But this is still very confusing, especially when this isn't just your personal project and other people might work on it.

    When I define an associative array, I don't expect it to make a difference whether I say
    PHP Code:
    array(
        
    'Justin' => 'Bieber'
        
    'Lady' => 'Gaga'

    or
    PHP Code:
    array(
        
    'Lady' => 'Gaga'
        
    'Justin' => 'Bieber'

    Your code will break that intuition.
    Very good point.

    This is all essentially for a MySQL query. I basically retrieve ALL values from the database, then pop those into an array then shuffle the array and then delete items from the end.

    Ideally, I'd like the deletion and randomness to be performed by MySQL but apparently RAND() is v.slow, any ideas here?
  10. #6
  11. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,908
    Rep Power
    6351
    ORDER BY RAND() is indeed slow, but it's still faster than loading an entire table into a PHP array and then truncating it.

    Array_slice() does what you want, but it's still a bit silly.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  12. #7
  13. No Profile Picture
    Contributing User
    Devshed Loyal (3000 - 3499 posts)

    Join Date
    Jul 2003
    Posts
    3,493
    Rep Power
    594
    On what do you base your conclusion that RAND() is significantly slower than what you are trying to do? Use RAND() and LIMIT, then you can eliminate all the PHP slicing and dicing.
    There are 10 kinds of people in the world. Those that understand binary and those that don't.
  14. #8
  15. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Mar 2013
    Posts
    12
    Rep Power
    0
    Originally Posted by gw1500se
    On what do you base your conclusion that RAND() is significantly slower than what you are trying to do? Use RAND() and LIMIT, then you can eliminate all the PHP slicing and dicing.
    I thought it'd be quicker - I'm quite a noob

    Sooo...how would I actually use RAND() and LIMIT to select, say, 10 random rows from a table?
  16. #9
  17. --
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Jul 2012
    Posts
    3,959
    Rep Power
    1014
    You should always aim for readability rather than performance, especially when you don't have much experience. If you do notice performance issues, you need to actually find the source before you can start optimizing.

    Don't try to solve supposed problems with supposed workarounds. This doesn't work and will leave you with a bunch of unreadable code, which might even be slower than the original idea. You should at least try the "slow approach" before concluding that it's slow.

    As to the RAND():
    Code:
    SELECT
    	foo
    	, bar
    FROM
    	yourtable
    ORDER BY
    	RAND()
    LIMIT
    	10
    If that's actually too slow (because you have hundreds of thousands of rows), there are many other approaches. Just Google for it.
    The 6 worst sins of security ē How to (properly) access a MySQL database with PHP

    Why canít I use certain words like "drop" as part of my Security Question answers?
    There are certain words used by hackers to try to gain access to systems and manipulate data; therefore, the following words are restricted: "select," "delete," "update," "insert," "drop" and "null".
  18. #10
  19. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    On what do you base your conclusion that RAND() is significantly slower than what you are trying to do? Use RAND() and LIMIT, then you can eliminate all the PHP slicing and dicing.
    If the size of the table is very small (a couple dozen records) then RAND()+LIMIT will work fine.

    "ORDER BY RAND()" requires MySQL to iterate through every row in the entire table, assign a temporary random value to it, then sort the entire table by that non-indexed temporary value, and only then can it actually apply the LIMIT. Even for medium sized tables the performance hit of sorting the entire table by a non-indexed value is usually too great.
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around

IMN logo majestic logo threadwatch logo seochat tools logo