digitalmars.D.learn - adding delegate to opApply
- berni (57/57) Sep 02 2019 I've tried to make a small example, but it's not easy to get this
- Paul Backus (10/18) Sep 02 2019 The delegate that gets passed to opApply is constructed from the
- berni (6/13) Sep 03 2019 Thanks for your answer. It's not exactly, what I was looking for,
I've tried to make a small example, but it's not easy to get this reduced further. At least I didn't manage. The following program can also be found at https://run.dlang.io/is/p6l7xN void main() { auto foo = Ways([Way([8,2,3,0]),Way([4,6,2]),Way([4,7,2,6])]); foo.remove_odds(); assert(foo==Ways([Way([8, 2]), Way([4, 6, 2]), Way([4]), Way([0]), Way([2, 6])])); } struct Ways { Way[] ways; void remove_odds() { Way[] new_ways; foreach (ref way;ways) foreach (point, void delegate(void delegate(Way way)) remove;way) if (point%2==1) remove(delegate(Way way) {new_ways ~= way;}); ways ~= new_ways; } } struct Way { int[] points; auto opApply(int delegate(int, void delegate(void delegate(Way way))) work) { size_t[] remove; void delegate(Way) add_new_way; foreach (index,point;points) if (auto result=work(point,(void delegate(Way) anw){remove~=index; add_new_way=anw;})) return result; import std.algorithm.sorting: sort; foreach (index;remove.sort!("a>b")) { add_new_way(Way(points[index+1..$])); points = points[0..index]; } return 0; } } I need to pass the delegate add_new_way somehow to opApply. Here I managed this, by adding this delegate to the remove-delegate and safe it away for further use. This works, because if remove is never called, add_new_way is not used either. But it's a little bit awkward. Is there a better way, to achieve this? (Note 1: In the real world, point%2==1 is a more complex function call. Note 2: The order of elements in Way[] way doesn't matter, if that makes things easier.) Maybe it's possible to work with something like std.algorithm.iteration.splitter instead of those loops and opApply. But splitter takes an element or a range, not a predicate.
Sep 02 2019
On Monday, 2 September 2019 at 12:43:31 UTC, berni wrote:I need to pass the delegate add_new_way somehow to opApply. Here I managed this, by adding this delegate to the remove-delegate and safe it away for further use. This works, because if remove is never called, add_new_way is not used either. But it's a little bit awkward. Is there a better way, to achieve this? (Note 1: In the real world, point%2==1 is a more complex function call. Note 2: The order of elements in Way[] way doesn't matter, if that makes things easier.)The delegate that gets passed to opApply is constructed from the body of the foreach loop; you don't (normally) pass it explicitly. If you have an existing delegate that you want to use with opApply, the easiest way is like this: void delegate(Thing) myDelegate = ...; foreach(thing; things) { myDelegate(thing); } // Equivalent to: things.opApply((Thing t) => myDelegate(t))
Sep 02 2019
On Monday, 2 September 2019 at 14:20:11 UTC, Paul Backus wrote:If you have an existing delegate that you want to use with opApply, the easiest way is like this: void delegate(Thing) myDelegate = ...; foreach(thing; things) { myDelegate(thing); } // Equivalent to: things.opApply((Thing t) => myDelegate(t))Thanks for your answer. It's not exactly, what I was looking for, but meanwhile I think, the whole idea was not reasonable. I meanwhile returned to using a normal function call instead of opApply, which makes it easy to pass a delegate as one of the parameters.
Sep 03 2019