digitalmars.D - opApply- and foreach-reverse request
- James Dunne (15/15) Feb 23 2005 I'd like to request an opApply-reverse operator and a new foreach-revers...
- Regan Heath (11/29) Feb 23 2005 Can't you go..
- James Dunne (7/40) Feb 23 2005 Not for a class. dup is a property of arrays. The function selectedInd...
- Regan Heath (12/61) Feb 23 2005 Ahh. ok. I see.
- James Dunne (12/34) Feb 23 2005 What does a class want to reverse? I know what you mean, but in a gener...
- Regan Heath (21/63) Feb 23 2005 I wasn't trying to imply all classes need one, or even all containers.
- James Dunne (18/26) Feb 23 2005 I agree with the options listed, and really they're not up to me to deci...
- Regan Heath (18/60) Feb 23 2005 Actually, I was being intentionally vague :)
- James Dunne (24/84) Feb 23 2005 Not necessarily. Foreach was created to iterate through lists. for() w...
- Ben Hinkle (19/35) Feb 24 2005 Start and stop is not needed since that is what slicing is for. Stepping...
- Manfred Nowak (11/12) Feb 25 2005 I am really stunned of this thread. I never heard of a construct in a
- Ben Hinkle (14/28) Feb 25 2005 That's a legit view. I've always viewed foreach as another kind of for
- Manfred Nowak (24/35) Feb 25 2005 For trees without any ordering of the nodes there are only two
- Regan Heath (20/109) Feb 24 2005 I believe the other important goal was to make iteration through a
- Georg Wrede (8/26) Feb 27 2005 That is certainly true. Rather break as much as needed right now,
- Ben Hinkle (20/40) Feb 23 2005 It would be nice to get something like it. I remember this coming when I...
- John Demme (6/13) Feb 23 2005 Sounds like you want the List template to have a backwards method that
- Ben Hinkle (4/18) Feb 23 2005 Yeah - that's what I did. I was describing how I implemented a similar
- Regan Heath (7/29) Feb 23 2005 It seems to me that it doesn't necessarily need to be a different class,...
- Ben Hinkle (13/43) Feb 23 2005 Two points:
- Regan Heath (21/68) Feb 23 2005 Yeah, this is what I was thinking about when I said that a different cla...
- Andy (66/135) Feb 23 2005 Wouldn't this serve for now at least? Personally I think it is better t...
- Ben Hinkle (54/125) Feb 24 2005 That's one way. Here's what I did in MinTL for backwards iteration over
- Andy Knowles (66/206) Feb 24 2005 Perhaps a good all round extension to the foreach statement would be if ...
- Ben Hinkle (38/40) Feb 25 2005 [mega-snip]
- James Dunne (7/25) Feb 23 2005 I'm proposing a new set of opApply and foreach constructs to simply prov...
- Ben Hinkle (6/19) Feb 23 2005 Yeah that might be best. I don't have a strong opinion about what the be...
- James Dunne (14/34) Feb 23 2005 I understand what you were doing with MinTL and the .backwards property....
- Ben Hinkle (12/25) Feb 24 2005 yes, you can. for example:
- James Dunne (7/22) Feb 24 2005 That's a new one to me! It's not explained in the documentation, so I d...
- Regan Heath (5/31) Feb 24 2005 IIRC the above doesn't give you 'sorted' information, so it's only reall...
- Ben Hinkle (7/35) Feb 25 2005 It would be nice to have more links between related sections of the doc....
- Georg Wrede (8/28) Feb 23 2005 Norbert & Co, should we have:
I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D? Regards, James Dunne
Feb 23 2005
On Wed, 23 Feb 2005 23:21:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D?Can't you go.. array = listBox.selectedIndices().dup; foreach(Item i; array.reverse) { } http://www.digitalmars.com/d/arrays.html "reverse" - "Reverses in place the order of the elements in the array. Returns the array." or, are you asking whether we want/need an operator or foreach instead? Regan
Feb 23 2005
In article <opsmocl1lz23k2f5 ally>, Regan Heath says...On Wed, 23 Feb 2005 23:21:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D?Can't you go.. array = listBox.selectedIndices().dup; foreach(Item i; array.reverse) { }Not for a class. dup is a property of arrays. The function selectedIndices() returns a class called SelectedIndexCollection which has opApply overloaded.http://www.digitalmars.com/d/arrays.html "reverse" - "Reverses in place the order of the elements in the array. Returns the array." or, are you asking whether we want/need an operator or foreach instead?We would need both opApplyReverse and foreachreverse in order to have it; I'm not sure I understand your question.ReganRegards, James Dunne
Feb 23 2005
On Thu, 24 Feb 2005 00:13:19 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmocl1lz23k2f5 ally>, Regan Heath says...Ahh. ok. I see. Ok, in order to be symetrical with an array, should it have a reverse method i.e. c = listBox.selectedIndices().reverse; foreach(Item i; c) { } Granted, a way to iterate backwards, or every 2nd,3rd,4th item .. without having to make a copy of the container would be useful and efficient.On Wed, 23 Feb 2005 23:21:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D?Can't you go.. array = listBox.selectedIndices().dup; foreach(Item i; array.reverse) { }Not for a class. dup is a property of arrays. The function selectedIndices() returns a class called SelectedIndexCollection which has opApply overloaded.I didn't realise your reply above, my question isn't relevant now :) Reganhttp://www.digitalmars.com/d/arrays.html "reverse" - "Reverses in place the order of the elements in the array. Returns the array." or, are you asking whether we want/need an operator or foreach instead?We would need both opApplyReverse and foreachreverse in order to have it; I'm not sure I understand your question.
Feb 23 2005
In article <opsmoeedwu23k2f5 ally>, Regan Heath says...On Thu, 24 Feb 2005 00:13:19 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:What does a class want to reverse? I know what you mean, but in a general sense, it's not very clear.In article <opsmocl1lz23k2f5 ally>, Regan Heath says...Ahh. ok. I see. Ok, in order to be symetrical with an array, should it have a reverse method i.e. c = listBox.selectedIndices().reverse; foreach(Item i; c) { }Can't you go.. array = listBox.selectedIndices().dup; foreach(Item i; array.reverse) { }Not for a class. dup is a property of arrays. The function selectedIndices() returns a class called SelectedIndexCollection which has opApply overloaded.Granted, a way to iterate backwards, or every 2nd,3rd,4th item .. without having to make a copy of the container would be useful and efficient.Exactly: without having to make a copy. foreachreverse would be implemented for arrays automatically, instead of having to use .dup .reverse. It's an in-place reverse iteration and won't cost any more than a forward iteration. There's really no reason not to have it. A foreachreverse (or whatever the syntax would be) would look much clearer to the naked eye that you are in fact reverse iterating through a class/array/struct. Regards, James Dunne
Feb 23 2005
On Thu, 24 Feb 2005 02:53:44 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmoeedwu23k2f5 ally>, Regan Heath says...I wasn't trying to imply all classes need one, or even all containers. Those classes that act as containers might want one, if it makes sense to reverse the contents of the container. eg. like it does for arrays, but not associative ones.On Thu, 24 Feb 2005 00:13:19 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:What does a class want to reverse? I know what you mean, but in a general sense, it's not very clear.In article <opsmocl1lz23k2f5 ally>, Regan Heath says...Ahh. ok. I see. Ok, in order to be symetrical with an array, should it have a reverse method i.e. c = listBox.selectedIndices().reverse; foreach(Item i; c) { }Can't you go.. array = listBox.selectedIndices().dup; foreach(Item i; array.reverse) { }Not for a class. dup is a property of arrays. The function selectedIndices() returns a class called SelectedIndexCollection which has opApply overloaded.I agree. You can still hand code it with a for loop, assuming that is, that you can access the items with [] and you know the last index. The idea behind foreach is to avoid having to code specifically for the container type. i.e. indexes, linklist etc. I think this, or similar idea, is required to achieve that goal.Granted, a way to iterate backwards, or every 2nd,3rd,4th item .. without having to make a copy of the container would be useful and efficient.Exactly: without having to make a copy. foreachreverse would be implemented for arrays automatically, instead of having to use .dup .reverse. It's an in-place reverse iteration and won't cost any more than a forward iteration. There's really no reason not to have it.A foreachreverse (or whatever the syntax would be) would look much clearer to the naked eye that you are in fact reverse iterating through a class/array/struct.foreach_r() maybe. Does the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach Regan
Feb 23 2005
In article <opsmol1osx23k2f5 ally>, Regan Heath says...Does the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with the options listed, and really they're not up to me to decide ;). On specifying the 'step' for the foreach, that doesn't seem especially useful unless it's either +1 or -1, which I'm sure is what your point was. I'm just saying I don't see why anyone would use a container to foreach through on a specified interval bigger than one. Maybe a punny syntax like "foreach" is short for forward-each, and we could have "backeach". foreach to me seems to imply order, and is usually implemented as a forward iteration. It would be clearer to specify new terms, one for forward, one for backward, but so much D code exists using 'foreach' and it'd be a pain to go thru and change all that. It's wisest to keep 'foreach' and 'opApply' and just add new terms for the reverse. 'foreach_r' seems appealing to me. opApply_r, on the other hand, does not. The other functions opAdd_r, etc. are used to handle cases where the first argument is not the 'this' pointer of the class, not to "reversely add" something, whatever that means ;). I'd suggest opApplyReverse in this case. Regards, James Dunne
Feb 23 2005
On Thu, 24 Feb 2005 03:41:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmol1osx23k2f5 ally>, Regan Heath says...Actually, I was being intentionally vague :)Does the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with the options listed, and really they're not up to me to decide ;). On specifying the 'step' for the foreach, that doesn't seem especially useful unless it's either +1 or -1, which I'm sure is what your point was.I'm just saying I don't see why anyone would use a container to foreach through on a specified interval bigger than one.Isn't it the same reason someone would use a for loop with i+=2, or i-=2? Of course in addition to the step you need some way to indicate where to start start, end, x. That is, unless you assume -1 means start at the end, and +1 means start at the beginning and that no-one ever wants to start elsewhere. I think the concept of direction and step can apply to arrays, linklists, and other types of containers, if so does that mean foreach should handle them?Maybe a punny syntax like "foreach" is short for forward-eachI thought it was "for each" as in "for each item in ..", and we could have "backeach". foreach to me seems to imply order, and is usually implemented as a forward iteration.I suspected that to others it might imply order.It would be clearer to specify new terms, one for forward, one for backward, but so much D code exists using 'foreach' and it'd be a pain to go thru and change all that.That was sort of my conclusion also.It's wisest to keep 'foreach' and 'opApply' and just add new terms for the reverse. 'foreach_r' seems appealing to me.Assuming there is no reason to want step then this option seems the best to me.opApply_r, on the other hand, does not. The other functions opAdd_r, etc. are used to handle cases where the first argument is not the 'this' pointer of the class, not to "reversely add" something, whatever that means ;). I'd suggest opApplyReverse in this case.I didn't think about the naming of opApply. Regan
Feb 23 2005
In article <opsmooadap23k2f5 ally>, Regan Heath says...On Thu, 24 Feb 2005 03:41:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:Not necessarily. Foreach was created to iterate through lists. for() was meant to give flexible looping ability. If you want to skip indicies, use a regular for() loop. Any well-implemented class that implements opApply (foreach support) should also implement opIndex to give access to individual elements. Besides, adding a step, start, and end to the current foreach syntax has the possibility of breaking code as it stands now. However, they could be optional arguments and not break anything, or they could be an optionally allowed syntax in addition to the "old (current) way".In article <opsmol1osx23k2f5 ally>, Regan Heath says...Actually, I was being intentionally vague :)Does the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with the options listed, and really they're not up to me to decide ;). On specifying the 'step' for the foreach, that doesn't seem especially useful unless it's either +1 or -1, which I'm sure is what your point was.I'm just saying I don't see why anyone would use a container to foreach through on a specified interval bigger than one.Isn't it the same reason someone would use a for loop with i+=2, or i-=2?Of course in addition to the step you need some way to indicate where to start start, end, x. That is, unless you assume -1 means start at the end, and +1 means start at the beginning and that no-one ever wants to start elsewhere. I think the concept of direction and step can apply to arrays, linklists, and other types of containers, if so does that mean foreach should handle them?If you can give me a legitimate example where you would *need* to skip elements on a constant step using foreach, then I'll agree with you. I just can't think of any off-hand.That's technically what it means, yes. But I was just throwing in the pun of foreach breaking up as "forward" and "each" to allow a backeach meaning "back" and "each". Just a dumb pun, don't worry about it ;)Maybe a punny syntax like "foreach" is short for forward-eachI thought it was "for each" as in "for each item in .."And it does. When you foreach through a D array, you iterate forward through it. It's just generally accepted that it has a forward order to it. In other, and we could have "backeach". foreach to me seems to imply order, and is usually implemented as a forward iteration.I suspected that to others it might imply order.Excellent!It would be clearer to specify new terms, one for forward, one for backward, but so much D code exists using 'foreach' and it'd be a pain to go thru and change all that.That was sort of my conclusion also.I just threw it out there, since it goes hand-in-hand with foreach. If we want to throw consistency and clarity out the window, opApply_r would be acceptable (and probably favorable to opApplyReverse). Regards, James DunneIt's wisest to keep 'foreach' and 'opApply' and just add new terms for the reverse. 'foreach_r' seems appealing to me.Assuming there is no reason to want step then this option seems the best to me.opApply_r, on the other hand, does not. The other functions opAdd_r, etc. are used to handle cases where the first argument is not the 'this' pointer of the class, not to "reversely add" something, whatever that means ;). I'd suggest opApplyReverse in this case.I didn't think about the naming of opApply.
Feb 23 2005
[snip]I think the options are: - add the ability to specify the 'step' in foreachNot necessarily. Foreach was created to iterate through lists. for() was meant to give flexible looping ability. If you want to skip indicies, use a regular for() loop. Any well-implemented class that implements opApply (foreach support) should also implement opIndex to give access to individual elements.Though [] indexing can be very slow in the middle of a linked list.Besides, adding a step, start, and end to the current foreach syntax has the possibility of breaking code as it stands now. However, they could be optional arguments and not break anything, or they could be an optionally allowed syntax in addition to the "old (current) way".Start and stop is not needed since that is what slicing is for. Stepping (I'm including reverse as the special case step = -1) is the only thing that isn't possible today without a "for" loop. This might have been proposed before- I can't remember. I think the following syntax is backwards compatible: foreach (ForeachTypeList; Expression [;Expression]) Statement where the optional second expression is the step. If the step is specified the opApply signature must match int opApply(int delegate(inout Type [, ...]) dg, int step); If there isn't an opApply with a step parameter it is an error. If the step is negative the traversal is backwards. Using a negative step as reverse means it is potentially a run-time decision. Also it isn't as explicit as having the word "reverse" or "backwards" or "_r" in there somewhere. But it would be nice to kill a few birds with one stone and it closely resembles how a for loop looks: for(start; stop; step) {...} foreach(iterator; container; step) {...}
Feb 24 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote: [...]foreach(iterator; container; step) {...}I am really stunned of this thread. I never heard of a construct in a meta language where "for each" is used without the meaning that whatever follows is to be interpreted as a set of items without any particular order. Am I out of bounds in this case? Can you show me an example where such thing is really used --- and of benefit? And please do not come with the example of a dictator who wants to shoot down every `step'th member of a town or elsewise defined group of people. -manfred
Feb 25 2005
"Manfred Nowak" <svv1999 hotmail.com> wrote in message news:cvn4bb$j49$1 digitaldaemon.com..."Ben Hinkle" <ben.hinkle gmail.com> wrote: [...]That's a legit view. I've always viewed foreach as another kind of for loop - one that handles tree traversals more cleanly than using STL-style iterators. The "each" in "foreach" indicates we go through a bunch of items, as you suggest, but I never got the impressions of any more semantics than that. I don't the see the usefulness of a step other than 1 or -1 for trees, though. but for lists of things it would be handy.foreach(iterator; container; step) {...}I am really stunned of this thread. I never heard of a construct in a meta language where "for each" is used without the meaning that whatever follows is to be interpreted as a set of items without any particular order.Am I out of bounds in this case?There is no spoon.Can you show me an example where such thing is really used --- and of benefit? And please do not come with the example of a dictator who wants to shoot down every `step'th member of a town or elsewise defined group of people. -manfredI'll give an example from MATLAB. It is common to pass around string-value lists like ['Color', 'red', 'LineWidth', 2.4, 'LineStyle', ,'--'] and then have code that runs down the strings or values by stepping by 2. An example closer to D would be having a list of points in a polygon and wanting to draw only every 3rd point for increased performance.
Feb 25 2005
"Ben Hinkle" <ben.hinkle gmail.com> wrote: [...]I don't the see the usefulness of a step other than 1 or -1 for trees, though. but for lists of things it would be handy.For trees without any ordering of the nodes there are only two natural traversals: breadth-first and depth-first and none of them maps to an integer in a natural way. If the tree is implemented as linked cells of an array, then there are two more "natural" traversals defined by the ordering of the cells of the array. And whenever I say "for each node in tree" I mean that the choosen traversal is unimportant, that is in addition to the free choosing of the traversal any permutations of the elements is allowed. The same holds for lists. Whenever the order does matter you have to describe how to choose the next element and that is done be a `for'-loop. On which criteria has the decision to be made to a `for' or a `foreach' if both have nearly identical semantics?I'll give an example from MATLAB. It is common to pass around string-value lists like ['Color', 'red', 'LineWidth', 2.4, 'LineStyle', ,'--'] and then have code that runs down the strings or values by stepping by 2. An example closer to D would be having a list of points in a polygon and wanting to draw only every 3rd point for increased performance.Thanks. But in both examples the order of the items does matter. And in the second example you said "every" not "each". SO it looks like you are talking about a new iterative statement `forevery' with a step-clause --- but not of modifying `foreach'. Then the syntax should look like forevery( step; container; iterator) -manfred -manfred
Feb 25 2005
On Thu, 24 Feb 2005 05:34:44 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmooadap23k2f5 ally>, Regan Heath says...I believe the other important goal was to make iteration through a container look identical, regardless of the container type. To save re-coding when changing container type, or writing generic code. If foreach can be modified to allow accessing every xth item of any container with the same syntax, regardless of type i.e. array, linklist, then I think this is the best solution. Given that opIndex for a linklist is inefficient, not having foreach do it, will mean people will use a for loop and be in the same situation as before foreach existed, recoding and having trouble writing generic code.On Thu, 24 Feb 2005 03:41:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:Not necessarily. Foreach was created to iterate through lists. for() was meant to give flexible looping ability. If you want to skip indicies, use a regular for() loop. Any well-implemented class that implements opApply (foreach support) should also implement opIndex to give access to individual elements.In article <opsmol1osx23k2f5 ally>, Regan Heath says...Actually, I was being intentionally vague :)Does the term "foreach" imply any direction forward or backward? To me it doesn't. I realise it's used in other languages, the same as in D, so it has a commonly understood meaning. I think the options are: - leave foreach, invent a backwards term i.e. foreach_r. - invent new terms, one for forward, one for backward. - add the ability to specify the 'step' in foreach ReganI agree with the options listed, and really they're not up to me to decide ;). On specifying the 'step' for the foreach, that doesn't seem especially useful unless it's either +1 or -1, which I'm sure is what your point was.I'm just saying I don't see why anyone would use a container to foreach through on a specified interval bigger than one.Isn't it the same reason someone would use a for loop with i+=2, or i-=2?Besides, adding a step, start, and end to the current foreach syntax has the possibility of breaking code as it stands now.I think breaking code pre 1.0 is ok, case by case, if we want to we'll have to consider it.However, they could be optional arguments and not break anything, or they could be an optionally allowed syntax in addition to the "old (current) way".This would be best if possible. Ben has come up with an idea I see.Do you want a concrete example? or are the comments above about the goal of foreach and linklists sufficient?Of course in addition to the step you need some way to indicate where to start start, end, x. That is, unless you assume -1 means start at the end, and +1 means start at the beginning and that no-one ever wants to start elsewhere. I think the concept of direction and step can apply to arrays, linklists, and other types of containers, if so does that mean foreach should handle them?If you can give me a legitimate example where you would *need* to skip elements on a constant step using foreach, then I'll agree with you. I just can't think of any off-hand.Ahh. Sorry, my sense of humour must have been on holiday.That's technically what it means, yes. But I was just throwing in the pun of foreach breaking up as "forward" and "each" to allow a backeach meaning "back" and "each". Just a dumb pun, don't worry about it ;)Maybe a punny syntax like "foreach" is short for forward-eachI thought it was "for each" as in "for each item in .."Yep. Tho, I am one of those that doesn't have a problem being different, if I think different is better. ReganAnd it does. When you foreach through a D array, you iterate forward through it. It's just generally accepted that it has a forward order to it. In other, and we could have "backeach". foreach to me seems to imply order, and is usually implemented as a forward iteration.I suspected that to others it might imply order.
Feb 24 2005
Regan Heath wrote:On Thu, 24 Feb 2005 05:34:44 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmooadap23k2f5 ally>, Regan Heath says...On Thu, 24 Feb 2005 03:41:02 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <opsmol1osx23k2f5 ally>, Regan Heath says...That is certainly true. Rather break as much as needed right now, than some later. Of course, any programmer who does even remotely "production" code does keep the precise version of compiler around. And for added security, zipped in the same file as his app sources! In a larger environment, of course the compiler versions are archeived anyway, so you only label the app as using V x.xx.0x.Besides, adding a step, start, and end to the current foreach syntax has the possibility of breaking code as it stands now.I think breaking code pre 1.0 is ok, case by case, if we want to we'll have to consider it.
Feb 27 2005
"James Dunne" <jdunne4 bradley.edu> wrote in message news:cvj34u$2b2s$1 digitaldaemon.com...I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D? Regards, James DunneIt would be nice to get something like it. I remember this coming when I was working on the containers in MinTL and so my solution there was to have a property called "backwards" on the container like List that returned a private struct that only implemented foreach (or something like that - I actually can't remember exactly without going and looking it up). So basically the user types List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place. I don't know if such a syntax would be a good idea in general. I suppose it depends on exactly how the type of x.backwards would work. Maybe it can have special behavior like "length" where it does magic things in different contexts (ironic that I'm saying this since I'm not a big fan of the magic length behavior).
Feb 23 2005
Ben Hinkle wrote:List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John
Feb 23 2005
"John Demme" <me teqdruid.com> wrote in message news:cvj6rk$2e8n$1 digitaldaemon.com...Ben Hinkle wrote:Yeah - that's what I did. I was describing how I implemented a similar feature for non-arrays as another data point in the discussion.List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John
Feb 23 2005
On Wed, 23 Feb 2005 19:53:27 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:"John Demme" <me teqdruid.com> wrote in message news:cvj6rk$2e8n$1 digitaldaemon.com...It seems to me that it doesn't necessarily need to be a different class, it could be another copy of the same class, containing the same info, backwards. Of course, sometimes a different class is preferrable. ReganBen Hinkle wrote:Yeah - that's what I did. I was describing how I implemented a similar feature for non-arrays as another data point in the discussion.List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John
Feb 23 2005
"Regan Heath" <regan netwin.co.nz> wrote in message news:opsmof4pem23k2f5 ally...On Wed, 23 Feb 2005 19:53:27 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:Two points: 1) it's actually a struct so that no garbage is created by foreaching backwards. If I had to choose between writing a for loop that steps backwards and writing a foreach loop that generating garbage I'd choose writing the for loop - but that's me. 2) a different type is needed because foreach on a regular List means forwards foreach and I decided that storing a flag as part of a general List just for backwards traversals wasn't worth the storage space. The actual implementation factors out the for loop into a function that the regular List calls with a step of +1 and the BackwardsList (or whatever name I used) calls with step -1."John Demme" <me teqdruid.com> wrote in message news:cvj6rk$2e8n$1 digitaldaemon.com...It seems to me that it doesn't necessarily need to be a different class, it could be another copy of the same class, containing the same info, backwards. Of course, sometimes a different class is preferrable. ReganBen Hinkle wrote:Yeah - that's what I did. I was describing how I implemented a similar feature for non-arrays as another data point in the discussion.List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John
Feb 23 2005
On Wed, 23 Feb 2005 21:02:15 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsmof4pem23k2f5 ally...Yeah, this is what I was thinking about when I said that a different class (I meant to include struct) was preferrable sometimes.On Wed, 23 Feb 2005 19:53:27 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:Two points: 1) it's actually a struct so that no garbage is created by foreaching backwards. If I had to choose between writing a for loop that steps backwards and writing a foreach loop that generating garbage I'd choose writing the for loop - but that's me."John Demme" <me teqdruid.com> wrote in message news:cvj6rk$2e8n$1 digitaldaemon.com...It seems to me that it doesn't necessarily need to be a different class, it could be another copy of the same class, containing the same info, backwards. Of course, sometimes a different class is preferrable. ReganBen Hinkle wrote:Yeah - that's what I did. I was describing how I implemented a similar feature for non-arrays as another data point in the discussion.List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John2) a different type is needed because foreach on a regular List means forwards foreach and I decided that storing a flag as part of a general List just for backwards traversals wasn't worth the storage space.You're probably right. Unless you were doing a lot of list reversals the common case would never need/use it. I was thinking that the simplest solution is to go: class List { List backwards() { List l = new List(); foreach(Item i; this) { l.addStart(i); } return l; } } in other words, make a new list, put the items in it in reverse order, return that. But, as you say, more garbage, less efficient.The actual implementation factors out the for loop into a function that the regular List calls with a step of +1 and the BackwardsList (or whatever name I used) calls with step -1.Cunning, I'll have to have a look at that code at some stage. Regan
Feb 23 2005
Wouldn't this serve for now at least? Personally I think it is better than adding new keywords/operators to the language... <code> module andy.backwards.backwards; import std.stdio; template backwards(List, Delegate) { struct reverse_iterator { List list; int opApply(Delegate dg) { return list.opApplyReverse(dg); } } reverse_iterator backwards() { reverse_iterator r; r.list = this; return r; } } class Foo { mixin backwards!(Foo, int delegate(inout int)); int opApply(int delegate(inout int) dg) { int result = 0; for(int i = 0; i < 10; i++) { result = dg(i); if(result) break; } return result; } int opApplyReverse(int delegate(inout int) dg) { int result = 0; for(int i = 9; i >= 0; i--) { result = dg(i); if(result) break; } return result; } } void main(char[][] args) { Foo foo = new Foo(); foreach(int i; foo) writefln(i); foreach(int i; foo.backwards) writefln(i); } </code> Adding a reverse iterator to a class requires only a mixin and the definition of the iterator itself (called opApplyReverse here). Calling the iterator requires only a .backwards on the end of the foreach expression. You can replace the templated delegate type with a templated item type to make typing the mixins easier, but then you can't create different iterators (say with an accompanying index). Hopefully with inlining and optomising this would be about as fast as normal foreaching? In article <opsmojp1qc23k2f5 ally>, Regan Heath says...On Wed, 23 Feb 2005 21:02:15 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:"Regan Heath" <regan netwin.co.nz> wrote in message news:opsmof4pem23k2f5 ally...Yeah, this is what I was thinking about when I said that a different class (I meant to include struct) was preferrable sometimes.On Wed, 23 Feb 2005 19:53:27 -0500, Ben Hinkle <ben.hinkle gmail.com> wrote:Two points: 1) it's actually a struct so that no garbage is created by foreaching backwards. If I had to choose between writing a for loop that steps backwards and writing a foreach loop that generating garbage I'd choose writing the for loop - but that's me."John Demme" <me teqdruid.com> wrote in message news:cvj6rk$2e8n$1 digitaldaemon.com...It seems to me that it doesn't necessarily need to be a different class, it could be another copy of the same class, containing the same info, backwards. Of course, sometimes a different class is preferrable. ReganBen Hinkle wrote:Yeah - that's what I did. I was describing how I implemented a similar feature for non-arrays as another data point in the discussion.List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.Sounds like you want the List template to have a backwards method that returns a class that will iterate over the original list backwards. Seems like a simple enough thing to do. Or do I misunderstand? John2) a different type is needed because foreach on a regular List means forwards foreach and I decided that storing a flag as part of a general List just for backwards traversals wasn't worth the storage space.You're probably right. Unless you were doing a lot of list reversals the common case would never need/use it. I was thinking that the simplest solution is to go: class List { List backwards() { List l = new List(); foreach(Item i; this) { l.addStart(i); } return l; } } in other words, make a new list, put the items in it in reverse order, return that. But, as you say, more garbage, less efficient.The actual implementation factors out the for loop into a function that the regular List calls with a step of +1 and the BackwardsList (or whatever name I used) calls with step -1.Cunning, I'll have to have a look at that code at some stage. Regan
Feb 23 2005
"Andy" <andy.knowles gmail.com> wrote in message news:cvjr4s$2kj$1 digitaldaemon.com...Wouldn't this serve for now at least? Personally I think it is better than adding new keywords/operators to the language... <code> module andy.backwards.backwards; import std.stdio; template backwards(List, Delegate) { struct reverse_iterator { List list; int opApply(Delegate dg) { return list.opApplyReverse(dg); } } reverse_iterator backwards() { reverse_iterator r; r.list = this; return r; } } class Foo { mixin backwards!(Foo, int delegate(inout int)); int opApply(int delegate(inout int) dg) { int result = 0; for(int i = 0; i < 10; i++) { result = dg(i); if(result) break; } return result; } int opApplyReverse(int delegate(inout int) dg) { int result = 0; for(int i = 9; i >= 0; i--) { result = dg(i); if(result) break; } return result; } } void main(char[][] args) { Foo foo = new Foo(); foreach(int i; foo) writefln(i); foreach(int i; foo.backwards) writefln(i); } </code> Adding a reverse iterator to a class requires only a mixin and the definition of the iterator itself (called opApplyReverse here). Calling the iterator requires only a .backwards on the end of the foreach expression. You can replace the templated delegate type with a templated item type to make typing the mixins easier, but then you can't create different iterators (say with an accompanying index). Hopefully with inlining and optomising this would be about as fast as normal foreaching?That's one way. Here's what I did in MinTL for backwards iteration over arrays. Actually the code in MinTL also can produce a "sequence" (which is a run-time list of items) from an array but I removed that part since it doesn't matter here. One decision I remember wondering about was the count in foreach statements - should it just count 0 to n-1 or should it count n-1 to 0? The code I have here counts 0 to n-1 but I'm thinking now maybe it should count n-1 to 0. /** Iterate backwards over a dynamic array. This function should be * used on the target array in a foreach statement * \param x the array to iterate over. */ template backwards(Value : Value[]) { DArrayReverseIter!(Value) backwards(Value[] x) { DArrayReverseIter!(Value) y; y.x = x; return y; } } /* Private helper for reverse iteration */ private struct DArrayReverseIter(Value) { Value[] x; int opApply(int delegate(inout Value val) dg) { int res = 0; for (int n=x.length; n > 0; ) { res = dg(x[--n]); if (res) break; } return res; } int opApply(int delegate(inout int n, inout Value val) dg) { int res = 0; int cnt = 0; for (int n=x.length; n > 0; cnt++) { res = dg(cnt,x[--n]); if (res) break; } return res; } } import std.stdio; int main() { int[] t1, t2; t1.length = 4; t2.length = 4; for(int k=0;k<4;k++) t1[k] = k*100; foreach(int n, int val; backwards!(int[])(t1)) { writefln("n=%d val=%d",n,val); t2[n] = val; } assert( t1.reverse == t2 ); return 0; }
Feb 24 2005
Perhaps a good all round extension to the foreach statement would be if it took delegates to iterators as well. Then the following would work: import std.stdio; class Foo { int opApply(int delegate(inout int) dg) { //default iterator return forwards(dg); } int forwards(int delegate(inout int) dg) { int result = 0; for(int i = 0; i < 10; i++) { result = dg(i); if(result) break; } return result; } int backwards(int delegate(inout int) dg) { int result = 0; for(int i = 9; i >= 0; i--) { result = dg(i); if(result) break; } return result; } } void main(char[][] args) { Foo foo = new Foo(); //implicit call to foo.opApply foreach(int i; foo) writefln(i); //explicit call to foo.opApply foreach(int i; &foo.opApply) writefln(i); //explicitly use forward iterator foreach(int i; &foo.forwards) writefln(i); //explicitly use reverse iterator foreach(int i; &foo.backwards) writefln(i); } The full type of the delegate would be int delegate(int delegate(inout _type_ [, ...])). I had a quick glance at the foreach conversion code in statement.c, this change should be pretty simple. This way you can have several named iterators on any class available for easy usage, say for different tree traversals. You could pass around iterators as delegates, allowing you to write code that operates on an entire collection while being completely independant of the type of the collection itself. If you really didn't like having the amperstand, you could write a public property to return a private delegate. And best of all, the only thing you have changed is the type of expression a foreach accepts. No new syntax, statements, operators, or types of expressions. Sound good? "Ben Hinkle" <ben.hinkle gmail.com> wrote in message news:cvkjv1$110l$1 digitaldaemon.com..."Andy" <andy.knowles gmail.com> wrote in message news:cvjr4s$2kj$1 digitaldaemon.com...toWouldn't this serve for now at least? Personally I think it is better than adding new keywords/operators to the language... <code> module andy.backwards.backwards; import std.stdio; template backwards(List, Delegate) { struct reverse_iterator { List list; int opApply(Delegate dg) { return list.opApplyReverse(dg); } } reverse_iterator backwards() { reverse_iterator r; r.list = this; return r; } } class Foo { mixin backwards!(Foo, int delegate(inout int)); int opApply(int delegate(inout int) dg) { int result = 0; for(int i = 0; i < 10; i++) { result = dg(i); if(result) break; } return result; } int opApplyReverse(int delegate(inout int) dg) { int result = 0; for(int i = 9; i >= 0; i--) { result = dg(i); if(result) break; } return result; } } void main(char[][] args) { Foo foo = new Foo(); foreach(int i; foo) writefln(i); foreach(int i; foo.backwards) writefln(i); } </code> Adding a reverse iterator to a class requires only a mixin and the definition of the iterator itself (called opApplyReverse here). Calling the iterator requires only a .backwards on the end of the foreach expression. You can replace the templated delegate type with a templated item typeamake typing the mixins easier, but then you can't create different iterators (say with an accompanying index). Hopefully with inlining and optomising this would be about as fast as normal foreaching?That's one way. Here's what I did in MinTL for backwards iteration over arrays. Actually the code in MinTL also can produce a "sequence" (which isrun-time list of items) from an array but I removed that part since it doesn't matter here. One decision I remember wondering about was the count in foreach statements - should it just count 0 to n-1 or should it countn-1to 0? The code I have here counts 0 to n-1 but I'm thinking now maybe it should count n-1 to 0. /** Iterate backwards over a dynamic array. This function should be * used on the target array in a foreach statement * \param x the array to iterate over. */ template backwards(Value : Value[]) { DArrayReverseIter!(Value) backwards(Value[] x) { DArrayReverseIter!(Value) y; y.x = x; return y; } } /* Private helper for reverse iteration */ private struct DArrayReverseIter(Value) { Value[] x; int opApply(int delegate(inout Value val) dg) { int res = 0; for (int n=x.length; n > 0; ) { res = dg(x[--n]); if (res) break; } return res; } int opApply(int delegate(inout int n, inout Value val) dg) { int res = 0; int cnt = 0; for (int n=x.length; n > 0; cnt++) { res = dg(cnt,x[--n]); if (res) break; } return res; } } import std.stdio; int main() { int[] t1, t2; t1.length = 4; t2.length = 4; for(int k=0;k<4;k++) t1[k] = k*100; foreach(int n, int val; backwards!(int[])(t1)) { writefln("n=%d val=%d",n,val); t2[n] = val; } assert( t1.reverse == t2 ); return 0; }
Feb 24 2005
"Andy Knowles" <andy.knowles gmail.com> wrote in message news:cvm7hp$2lr4$1 digitaldaemon.com...Perhaps a good all round extension to the foreach statement would be if it took delegates to iterators as well.[mega-snip] That is a pretty neat idea. It got me thinking. A post of Manfred's on this thread mentioned breadth-first and depth-first traversals and it would be nice to be able to specify which kind of traversal you want in a foreach (if the tree supplied those). Using your propsed syntax, foreach(int i; &foo.breadthFirst) writefln(i); foreach(int i, &foo.depthFirst) writefln(i); (plus most likely the reverse versions of breadth and depth first). Yet another way to skin this cat is to allow trailing parameters to foreach. For example class Foo { int opApply(int delegate(inout int) dg, bool reverse = false) { ... } } that can be used like foreach(int x; obj) { ... } % called with reverse = false or foreach(int x; obj; true) { ... }% called with reverse = true Or users can pass a step parameter if allowed: class Foo { int opApply(int delegate(inout int) dg, int step = 1) { ... } } foreach(int x; obj; 2) { ... }% called with step = 2 Or users can pass a flag for tree traversals: const int BreathFirst = 0; const int DepthFirst = 1; class Tree { int opApply(int delegate(inout int) dg, int method = BreadthFirst) { ... } } foreach(int x; obj) { ... }% called with method = BreadthFirst foreach(int x; obj; DepthFirst) { ... }% called with method = DepthFirst Anyhow, I hope foreach gets something like any of these ideas- it would be pretty useful to customize traversals. -Ben
Feb 25 2005
In article <cvj669$2dtp$1 digitaldaemon.com>, Ben Hinkle says...It would be nice to get something like it. I remember this coming when I was working on the containers in MinTL and so my solution there was to have a property called "backwards" on the container like List that returned a private struct that only implemented foreach (or something like that - I actually can't remember exactly without going and looking it up). So basically the user types List!(int) x; ... foreach(int item; x.backwards) { .... } to iterate backwards over a list. The "reverse" property of List works just like the array reverse property and reverses the list items in-place.You were clear up to this point... You lost me on this next paragraph.I don't know if such a syntax would be a good idea in general. I suppose it depends on exactly how the type of x.backwards would work. Maybe it can have special behavior like "length" where it does magic things in different contexts (ironic that I'm saying this since I'm not a big fan of the magic length behavior).I'm proposing a new set of opApply and foreach constructs to simply provide support for reverse iteration. No special hacks need be introduced. Keep it simple and sweet. Regards, James Dunne
Feb 23 2005
Yeah that might be best. I don't have a strong opinion about what the best answer would be. I was exploring a solution that didn't involve adding a keyword. A reverse foreach over associative arrays isn't needed because the order is random anyway so should AA's be foreachreverse-able? Maybe there's some solution involving adding a stepsize argument to the foreach and saying that negative step sizes are reverse traversals? eh, I don't know.I don't know if such a syntax would be a good idea in general. I suppose it depends on exactly how the type of x.backwards would work. Maybe it can have special behavior like "length" where it does magic things in different contexts (ironic that I'm saying this since I'm not a big fan of the magic length behavior).I'm proposing a new set of opApply and foreach constructs to simply provide support for reverse iteration. No special hacks need be introduced. Keep it simple and sweet.
Feb 23 2005
In article <cvjgro$2odu$1 digitaldaemon.com>, Ben Hinkle says...I understand what you were doing with MinTL and the .backwards property. I'd like to try to accomplish it without any memory duplication or "garbage produced." If that involves adding a new keyword to the language, that's fine with me! You can't foreach on an AA by itself, you have to foreach on the .keys or the values properties of the AA, which are just regular arrays. So if the foreach-reverse keyword is introduced, you'd reverse iterate on the keys or the values of the AA. Of course, reverse iteration on the keys or values doesn't matter much, unless you want to reverse iterate through the SORTED keys or values, which DOES make sense. :) Regards, James DunneYeah that might be best. I don't have a strong opinion about what the best answer would be. I was exploring a solution that didn't involve adding a keyword. A reverse foreach over associative arrays isn't needed because the order is random anyway so should AA's be foreachreverse-able? Maybe there's some solution involving adding a stepsize argument to the foreach and saying that negative step sizes are reverse traversals? eh, I don't know.I don't know if such a syntax would be a good idea in general. I suppose it depends on exactly how the type of x.backwards would work. Maybe it can have special behavior like "length" where it does magic things in different contexts (ironic that I'm saying this since I'm not a big fan of the magic length behavior).I'm proposing a new set of opApply and foreach constructs to simply provide support for reverse iteration. No special hacks need be introduced. Keep it simple and sweet.
Feb 23 2005
You can't foreach on an AA by itself, you have to foreach on the .keys or the values properties of the AA, which are just regular arrays.yes, you can. for example: import std.stdio; int main() { int[int] x; x[100]=1; x[-100]=2; x[10]=3; foreach(int key, int val; x) { writefln("key %d val %d",key,val); } return 0; }So if the foreach-reverse keyword is introduced, you'd reverse iterate on the keys or the values of the AA. Of course, reverse iteration on the keys or values doesn't matter much, unless you want to reverse iterate through the SORTED keys or values, which DOES make sense. :) Regards, James Dunne
Feb 24 2005
In article <cvkk7t$1194$1 digitaldaemon.com>, Ben Hinkle says...That's a new one to me! It's not explained in the documentation, so I didn't think it existed. Looks like I have to do some research on the foreach allowable syntax to see what it's really capable of. This could just boil down to a simple documentation problem (or lack thereof). Regards, James DunneYou can't foreach on an AA by itself, you have to foreach on the .keys or the values properties of the AA, which are just regular arrays.yes, you can. for example: import std.stdio; int main() { int[int] x; x[100]=1; x[-100]=2; x[10]=3; foreach(int key, int val; x) { writefln("key %d val %d",key,val); } return 0; }
Feb 24 2005
On Fri, 25 Feb 2005 00:58:20 +0000 (UTC), James Dunne <jdunne4 bradley.edu> wrote:In article <cvkk7t$1194$1 digitaldaemon.com>, Ben Hinkle says...IIRC the above doesn't give you 'sorted' information, so it's only really good if you don't care about what order it comes out in. ReganThat's a new one to me! It's not explained in the documentation, so I didn't think it existed. Looks like I have to do some research on the foreach allowable syntax to see what it's really capable of. This could just boil down to a simple documentation problem (or lack thereof).You can't foreach on an AA by itself, you have to foreach on the .keys or the values properties of the AA, which are just regular arrays.yes, you can. for example: import std.stdio; int main() { int[int] x; x[100]=1; x[-100]=2; x[10]=3; foreach(int key, int val; x) { writefln("key %d val %d",key,val); } return 0; }
Feb 24 2005
"James Dunne" <jdunne4 bradley.edu> wrote in message news:cvlt7c$2csq$1 digitaldaemon.com...In article <cvkk7t$1194$1 digitaldaemon.com>, Ben Hinkle says...It would be nice to have more links between related sections of the doc. The stuff about assoc arrays and foreach is under the "foreach" help. See http://www.digitalmars.com/d/statement.html#foreach the paragraph starting with "If the aggregate expression is an associative array"That's a new one to me! It's not explained in the documentation, so I didn't think it existed. Looks like I have to do some research on the foreach allowable syntax to see what it's really capable of. This could just boil down to a simple documentation problem (or lack thereof). Regards, James DunneYou can't foreach on an AA by itself, you have to foreach on the .keys or the values properties of the AA, which are just regular arrays.yes, you can. for example: import std.stdio; int main() { int[int] x; x[100]=1; x[-100]=2; x[10]=3; foreach(int key, int val; x) { writefln("key %d val %d",key,val); } return 0; }
Feb 25 2005
James Dunne wrote:I'd like to request an opApply-reverse operator and a new foreach-reverse construct (syntax up for discussion, don't flame me for my -reverse's). Possible syntax: opApplyReverse and foreachreverse (or just foreachr) This would be especially useful for some lists you need to iterate through in reverse. You could have both the forward iterator and reverse iterator versions in the same class. I came across this while coding with DFL. I need to delete the selected items from a ListBox control. The ListBox offers a property called selectedIndices(), and if you delete them in order, all the indices after the one you just deleted become invalid (shifted up by one). The correct way to do it would be to reverse iterate through the selectedIndices and delete them. That way no indices would be invalid after you delete them. Anyone else think this would be a valuable addition to D? Regards, James DunneNorbert & Co, should we have: foreach (i in m..n) // itreate in no particular order a[i] = b[i] + 3 * c[i]; in addition to the (quite cool) "existing" vectorising syntax? (and of course, to avoid hierarchy:) foreach (i in a..b, j in c..d, k in e..f) a[i,j,k] = foo_op(x,y,z[j+i+k-2]); // or whatever
Feb 23 2005