Req #80120 [Fbk->Nab]: ForEach() backwards support?

From: Date: Fri, 18 Sep 2020 19:59:09 +0000
Subject: Req #80120 [Fbk->Nab]: ForEach() backwards support?
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-229080@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=80120&edit=1 ID: 80120 Updated by: requinix@php.net Reported by: divinity76 at gmail dot com Summary: ForEach() backwards support? -Status: Feedback +Status: Not a bug Type: Feature/Change Request Package: *General Issues PHP Version: Next Minor Version Block user comment: N Private report: N New Comment: > there's no place where iterating forward manually is "too hard" either, right? > ^^ You know that the alternative is using reset() + next() + key() + current()? So yes, it *is* too hard to do that manually :p If you feel strongly that a reverse-foreach would be beneficial to PHP then you should spend some time thinking about exactly how it would work, and when you're ready to talk about it you can hit up the internals mailing list with your ideas. https://wiki.php.net/rfc/howto Otherwise, given (1) there is no blatantly obvious syntax for this new foreach behavior to use, (2) it won't work with iterators/generators, and (3) the alternative of a for loop or array_reverse() isn't too complicated to ask for, I don't think this will work out. (more on #2: a reverse foreach could automagically call iterator_to_array() and array_reverse(), however there are too many times when that isn't safe to do; PHP cannot detect an infinite iterator, or one that has unpleasant side effects, or one that would consume too much memory if everything were collected at once, so it needs to be up to the developer to decide how to proceed. Perhaps the best solution to reversing the data lies with an ORDER BY x DESC, or calling an API with a sort=desc parameter?) Previous Comments: ------------------------------------------------------------------------ [2020-09-18 17:19:40] divinity76 at gmail dot com @requinix > For one, this isn't going to work with iterators. Those can only run in one direction. huh, that's a good point. probably won't work with generators/yield either (especially infinite generators with a foreach() containing break; or return; ) > Is there a case where it's "too hard" to do it in reverse manually? no, not really, there's just cases where foreach() would be easier, and that's the reason foreach() exist in the first place; there's no place where iterating forward manually is "too hard" either, right? ^^ ------------------------------------------------------------------------ [2020-09-18 16:20:02] requinix@php.net For one, this isn't going to work with iterators. Those can only run in one direction. But I'm not sure why this needs to be a feature. It's not hard to set up for loops on arrays, and with iterators there's iterator_to_array + array_reverse (if you know it's safe to do so). Is there a case where it's "too hard" to do it in reverse manually? ------------------------------------------------------------------------ [2020-09-18 08:33:26] divinity76 at gmail dot com Description: ------------ There are situations where one want to iterate a list backwards, I was recently in such a situation, writing: <?php $removeWhitespaceTextNodes = function (\DOMNode $node) use (&$removeWhitespaceTextNodes): void { if ($node->hasChildNodes()) { // Warning: it's important to do it backwards; if you do it forwards, the index for DOMNodeList might become invalidated; // that's why i don't use ForEach() - don't change it (unless you know what you're doing, ofc) for ($i = $node->childNodes->length - 1; $i >= 0; --$i) { $removeWhitespaceTextNodes($node->childNodes->item($i)); } } if ($node->nodeType === XML_TEXT_NODE && !$node->hasChildNodes() && !$node->hasAttributes() && (strlen(trim($node->textContent)) === 0)) { $node->parentNode->removeChild($node); } }; ?> I think it could be useful if ForEach() could iterate stuff backwards, maybe something like: <?php ForEach($iterable as $index=>$val, $flags = 0){} ?> (with a new FOREACH_BACKWARDS flag) or maybe just <?php ForEach($iterable as $index=>$val, bool $backwards = false){} ?> or something like that? ------------------------------------------------------------------------ -- Edit this bug report at https://bugs.php.net/bug.php?id=80120&edit=1

« previous php.bugs (#229080) next »