digitalmars.D.learn - lockstep alternative for StoppingPolicy.longest
- Andrej Mitrovic (17/17) Sep 17 2012 I need to iterate through two arrays and do some special comparisons,
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (18/35) Sep 17 2012 I think you actually want .shortest, no? lockstep's cousin zip() and
- Andrej Mitrovic (45/46) Sep 17 2012 No I want to continue iterating as long as one of the ranges is still
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (12/58) Sep 17 2012 Then .longest with zip seems to be the way to go. zip() produces the
- Andrej Mitrovic (3/4) Sep 17 2012 Ah ain't that cool. It looks like it works. What does it use for the
- Andrej Mitrovic (2/6) Sep 17 2012 Yep just tried with floats and returns NaN. Thanks again, Ali! :)
- Andrej Mitrovic (3/8) Sep 17 2012 Gah I've messed up the simple example. If aa was a sentinel then it
- Andrej Mitrovic (7/15) Sep 17 2012 Here we go: http://dpaste.dzfl.pl/dff850fb
I need to iterate through two arrays and do some special comparisons, but the arrays are not guaranteed to have the same length. lockstep doesn't work with the "longest" policy, e.g.: int[] a = [1, 2]; int[] b = [1, 2, 3]; foreach (aa, bb; lockstep(a, b, StoppingPolicy.longest)) // throws { } What I would like to have is the ability to set a sentinel value when .empty returns true for one of the arrays, this would enable this policy to work. For example I could have: foreach (aa, bb; lockstep(a, b, StoppingPolicy.longest, -1)) // sentinel is -1 { // if aa or bb doesn't exist it's set to -1 } or alternatively aa/bb could be pointers, and the sentinel would conveniently be null. Is anything like this in Phobos already?
Sep 17 2012
On 09/17/2012 03:00 PM, Andrej Mitrovic wrote:I need to iterate through two arrays and do some special comparisons, but the arrays are not guaranteed to have the same length. lockstep doesn't work with the "longest" policy, e.g.: int[] a = [1, 2]; int[] b = [1, 2, 3]; foreach (aa, bb; lockstep(a, b, StoppingPolicy.longest)) // throws { } What I would like to have is the ability to set a sentinel value when .empty returns true for one of the arrays, this would enable this policy to work. For example I could have: foreach (aa, bb; lockstep(a, b, StoppingPolicy.longest, -1)) // sentinel is -1 { // if aa or bb doesn't exist it's set to -1 } or alternatively aa/bb could be pointers, and the sentinel would conveniently be null. Is anything like this in Phobos already?I think you actually want .shortest, no? lockstep's cousin zip() and until() may help: import std.stdio; import std.range; import std.algorithm; void main() { int i, j, k, l, m; int*[] a = [&i, null, &j]; int*[] b = [&k, &l, &m]; foreach (aa, bb; zip(StoppingPolicy.shortest, until!(x => x is null)(a), b)) { writefln("%s and %s", aa, bb); } } Ali
Sep 17 2012
On 9/18/12, Ali =C7ehreli <acehreli yahoo.com> wrote:I think you actually want .shortest, no?No I want to continue iterating as long as one of the ranges is still not empty. I'm not doing just comparisons, once there's only one range that's not empty I have to do some special checks on its elements. In simple terms: void main() { enum sentinel =3D -1; // imagine 3rd element missing and lockstep replaces it with -1 int[] arr1 =3D [2, 4, -1]; int[] arr2 =3D [2, 4, 3]; bool state; foreach (aa, bb; lockstep(arr1, arr2)) { if (aa =3D=3D sentinel) { if (aa % 2 =3D=3D 0) { state =3D true; break; } } else if (bb =3D=3D sentinel) { if (bb % 2 =3D=3D 0) { state =3D true; break; } } else { if (aa =3D=3D bb) { state =3D true; break; } } } } That's not the algorithm I'm using and I'm not dealing with integers but that's just an example. If either range is empty I want to continue doing some special work on the range that isn't empty, otherwise I have to do work on both.
Sep 17 2012
On 09/17/2012 03:51 PM, Andrej Mitrovic wrote:On 9/18/12, Ali Çehreli<acehreli yahoo.com> wrote:Then .longest with zip seems to be the way to go. zip() produces the .init value for the short range. Luckily, you are not dealing with int.init so perhaps your type's sentinel is distinguishable: foreach (aa, bb; zip(StoppingPolicy.longest, a, b)) { if (aa == aa.init) { } // etc. writefln("%s and %s", aa, bb); } AliI think you actually want .shortest, no?No I want to continue iterating as long as one of the ranges is still not empty. I'm not doing just comparisons, once there's only one range that's not empty I have to do some special checks on its elements. In simple terms: void main() { enum sentinel = -1; // imagine 3rd element missing and lockstep replaces it with -1 int[] arr1 = [2, 4, -1]; int[] arr2 = [2, 4, 3]; bool state; foreach (aa, bb; lockstep(arr1, arr2)) { if (aa == sentinel) { if (aa % 2 == 0) { state = true; break; } } else if (bb == sentinel) { if (bb % 2 == 0) { state = true; break; } } else { if (aa == bb) { state = true; break; } } } } That's not the algorithm I'm using and I'm not dealing with integers but that's just an example. If either range is empty I want to continue doing some special work on the range that isn't empty, otherwise I have to do work on both.
Sep 17 2012
On 9/18/12, Ali =C7ehreli <acehreli yahoo.com> wrote:Then .longest with zip seems to be the way to go.Ah ain't that cool. It looks like it works. What does it use for the sentinel, Type.init perhaps?
Sep 17 2012
On 9/18/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 9/18/12, Ali =C7ehreli <acehreli yahoo.com> wrote:Yep just tried with floats and returns NaN. Thanks again, Ali! :)Then .longest with zip seems to be the way to go.Ah ain't that cool. It looks like it works. What does it use for the sentinel, Type.init perhaps?
Sep 17 2012
On 9/18/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:foreach (aa, bb; lockstep(arr1, arr2)) { if (aa == sentinel) { if (aa % 2 == 0)Gah I've messed up the simple example. If aa was a sentinel then it meant I wouldn't check it at all, I'd try to check 'bb' instead.
Sep 17 2012
On 9/18/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:On 9/18/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Here we go: http://dpaste.dzfl.pl/dff850fb Hardcoded but could be made to work with multiple ranges (+ i have way too many runtime checks there). For floating-point this might even work since a sentinel could be NaN, but for ints there's no reasonable sentinel. We could use pointers instead and use NULL when the range is empty.foreach (aa, bb; lockstep(arr1, arr2)) { if (aa == sentinel) { if (aa % 2 == 0)Gah I've messed up the simple example. If aa was a sentinel then it meant I wouldn't check it at all, I'd try to check 'bb' instead.
Sep 17 2012