mindplay.dk Posted November 5, 2012 Share Posted November 5, 2012 WireArray::getRandom() can be "too" random for my taste - I wanted some Page items to rotate randomly on a daily basis, rather than every page load, so I came up with this: /** * Select random pages from a PageArray * * If no $seed is provided, today's date is used to seed the random number * generator, so you can use this function to rotate items on a daily basis. * * @param PageArray $pages the list of Page object to select from * @param int $amount the amount of items to extract from the given list * @param int|null $seed a number used to see the random number generator */ public function randomPages(PageArray $pages, $amount=1, $seed=null) { if ($seed === null) { $seed = crc32(date('Ymd')); } srand($seed); $keys = $pages->getKeys(); $selected = new PageArray(); while (count($keys) > 0 && count($selected) < $amount) { $index = rand(0, count($keys)-1); $key = $keys[$index]; $selected->add($pages[$key]); array_splice($keys, $index, 1); } return $selected; } I thought I would post it here for others to use. I wonder if this is useful enough that it (or something similar) should be part of the core? I personally find that "totally random" is rarely useful or desirable in real life - for one, pages that change on every request may harm your search-engine ranking. For another, users may find it confusing that your site changes all the time - "hey, what was that thing I just saw" doesn't work for the person who goes back to the front-page to see "that other thing" he just saw, when you constantly swap things out between every page view... Just my opinion, for what it's worth 1 Link to comment Share on other sites More sharing options...
mindplay.dk Posted November 5, 2012 Author Share Posted November 5, 2012 Perhaps even better: /** * Select random pages from a PageArray * * If no $seed is provided, today's date is used to seed the random number * generator, so you can use this function to rotate items on a daily basis. * * @param PageArray $pages the list of Page object to select from * @param int $amount the amount of items to extract from the given list * @param int|string $seed a number used to see the random number generator; or a string compatible with date() */ public function randomPages(PageArray $pages, $amount=1, $seed='Ymd') { if (is_string($seed)) { $seed = crc32(date($seed)); } srand($seed); $keys = $pages->getKeys(); $selected = new PageArray(); while (count($keys) > 0 && count($selected) < $amount) { $index = rand(0, count($keys)-1); $key = $keys[$index]; $selected->add($pages[$key]); array_splice($keys, $index, 1); } return $selected; } Now you can seed with a date()-compatible string, so you can rotate weekly (for example) using "YW", or monthly using "Ym", etc. 5 Link to comment Share on other sites More sharing options...
ryan Posted November 5, 2012 Share Posted November 5, 2012 I agree this does seem really useful, thanks for posting it. I can think of a lot of situations where I really should be using this rather than the existing getRandom(). Rather than adding to PageArray, it seems like the value could extend further than just pages and perhaps it belongs in WireArray instead? (which would be inherited by PageArray) I'm thinking name should be: getRandomInterval(), getRandomTimed() ... or some name that alludes to what differentiates it from getRandom()? Link to comment Share on other sites More sharing options...
mindplay.dk Posted November 7, 2012 Author Share Posted November 7, 2012 Yes, this would be generally useful in PageArray, good point. As for the method-name, good question... would it make sense to just have this as an optional argument on getRandom() ? Link to comment Share on other sites More sharing options...
ryan Posted November 8, 2012 Share Posted November 8, 2012 For the most part, I usually prefer more functions to more arguments. This is one reason why I've never been too happy with that second $alwaysArray argument to the current getRandom() function. I should have had just getRandom() that always returns 1, and findRandom() that always returns a WireArray/PageArray. So while it could be added to getRandom(); I think the value of it might be easy for people to miss, because it'd be a 3rd argument. So here's what I did instead: https://github.com/r...329a491e9d77b0a See the new functions added: findRandom() and findRandomTimed(). Adding the findRandom() function helps to get the API clarity it was missing before, and gives findRandomTimed() more context. Of course, getRandom() will still return more than 1 if you tell it to, as I wouldn't want to break compatibility. But if I could go back in time, I would make getRandom() always return 1 and have no arguments. Link to comment Share on other sites More sharing options...
mindplay.dk Posted November 8, 2012 Author Share Posted November 8, 2012 Looks fine to me, How about findRandomSeed() or findRandomSeeded() ? ... it's not really limited to time periods, you can seed it with whatever. Link to comment Share on other sites More sharing options...
ryan Posted November 9, 2012 Share Posted November 9, 2012 Seeded is a more accurate description I agree. But for me the concern is the term... how many people know what "seeded" means? I went back and forth on it a few times, but since the default behavior is to return a random result within a timed/daily period, I figured we'd let the function describe the default behavior. The advanced people will be able to figure out how to make it do something different, whereas the non-advanced people might completely miss the big value in this function otherwise. I could be wrong, but am guessing 99% of the time, people would be using this function in a timed fashion rather than some other kind of seed? At least, I haven't been able to think of other scenarios yet. Link to comment Share on other sites More sharing options...
mindplay.dk Posted November 9, 2012 Author Share Posted November 9, 2012 All good points. Let's name it according to the primary use-case then - how about rotate() or alternate() ? Link to comment Share on other sites More sharing options...
Soma Posted November 9, 2012 Share Posted November 9, 2012 How about findRandomDelayed() or findRandomInterval() ? 1 Link to comment Share on other sites More sharing options...
apeisa Posted November 9, 2012 Share Posted November 9, 2012 +1 to findRandomInterval() Also, agree with Mindplay here - a great addition and many times more useful than "total random"! 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now