Re: countUntil to print all the index of a given string.
On Sunday, 25 February 2018 at 13:25:56 UTC, Vino wrote: On Sunday, 25 February 2018 at 03:41:27 UTC, Jonathan M Davis wrote: On Sunday, February 25, 2018 02:58:33 Seb via Digitalmars-d-learn wrote: [...] That will help eventually, but it requires a compiler flag, so it's really not going to help for code in general right now, and the fact that that DIP does nothing to solve the problem of how to create exception messages without allocating them on the GC heap means that exceptions in general are still frequently going to result in allocations unless you jump through several hoops to be able to create an exception message that's in a static array or malloc-ed or something. So, I don't know how much it's going to help in practice outside of code where the programmer is absolutely determined to have no GC allocations. [...] Yeah. There does tend to be a correlation between @nogc and whether a range is lazy, but it's not guaranteed, so I'm inclined to think that it's a poor idea to rely on it and that it's just ultimately better to look at the documentation or even the code. - Jonathan M Davis Hi All, Sorry, I am not able to see any correlation between the raised topic and the conversation that is happening in this forum, could any one please explain on of what is going on and how do you thing that this conversation is related to the topic raised, if not would suggest you to open a new topic. From, Vino.B I think this will work: import std.container; import std.algorithm; import std.range; import std.stdio; void main () { auto a = Array!string("Test1", "Test2", "Test3", "Test1", "Test2"); auto b = Array!string("Test1", "Test2", "Test3"); foreach(i; b[]) a[].enumerate.filter!(a => a[1] == i).map!(a => a[0]).SList!size_t[].writeln;
Re: countUntil to print all the index of a given string.
On Sunday, 25 February 2018 at 03:41:27 UTC, Jonathan M Davis wrote: On Sunday, February 25, 2018 02:58:33 Seb via Digitalmars-d-learn wrote: [...] That will help eventually, but it requires a compiler flag, so it's really not going to help for code in general right now, and the fact that that DIP does nothing to solve the problem of how to create exception messages without allocating them on the GC heap means that exceptions in general are still frequently going to result in allocations unless you jump through several hoops to be able to create an exception message that's in a static array or malloc-ed or something. So, I don't know how much it's going to help in practice outside of code where the programmer is absolutely determined to have no GC allocations. [...] Yeah. There does tend to be a correlation between @nogc and whether a range is lazy, but it's not guaranteed, so I'm inclined to think that it's a poor idea to rely on it and that it's just ultimately better to look at the documentation or even the code. - Jonathan M Davis Hi All, Sorry, I am not able to see any correlation between the raised topic and the conversation that is happening in this forum, could any one please explain on of what is going on and how do you thing that this conversation is related to the topic raised, if not would suggest you to open a new topic. From, Vino.B
Re: countUntil to print all the index of a given string.
On Sunday, February 25, 2018 02:58:33 Seb via Digitalmars-d-learn wrote: > On Sunday, 25 February 2018 at 02:37:00 UTC, Jonathan M Davis > > wrote: > > If any exceptions could be thrown, then a lazy solution can't > > be @nogc (something that's often the case with strings thanks > > to auto-decoding and UTFExceptions), and a solution could be > > eager without allocating if the result doesn't require any > > allocation. > > FYI -dip1008 is a thing now and part of 2.079. > See also: > > https://dlang.org/changelog/pending.html#dip1008 > https://run.dlang.io/is/clNX6G > https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md That will help eventually, but it requires a compiler flag, so it's really not going to help for code in general right now, and the fact that that DIP does nothing to solve the problem of how to create exception messages without allocating them on the GC heap means that exceptions in general are still frequently going to result in allocations unless you jump through several hoops to be able to create an exception message that's in a static array or malloc-ed or something. So, I don't know how much it's going to help in practice outside of code where the programmer is absolutely determined to have no GC allocations. > > Also, you could have a lazy range that involves a lambda that > > allocates a closure. > > Of course, or a @nogc range that allocates with malloc or eagerly > steps through the entire range. > > Anyhow I just mentioned it because it's the best form of > automatic checking that we have (what the OP was asking for) and > in many cases when an algorithm can't be @nogc it does allocate > somewhere which is a red flag. Yeah. There does tend to be a correlation between @nogc and whether a range is lazy, but it's not guaranteed, so I'm inclined to think that it's a poor idea to rely on it and that it's just ultimately better to look at the documentation or even the code. - Jonathan M Davis
Re: countUntil to print all the index of a given string.
On Sunday, 25 February 2018 at 02:37:00 UTC, Jonathan M Davis wrote: If any exceptions could be thrown, then a lazy solution can't be @nogc (something that's often the case with strings thanks to auto-decoding and UTFExceptions), and a solution could be eager without allocating if the result doesn't require any allocation. FYI -dip1008 is a thing now and part of 2.079. See also: https://dlang.org/changelog/pending.html#dip1008 https://run.dlang.io/is/clNX6G https://github.com/dlang/DIPs/blob/master/DIPs/DIP1008.md Also, you could have a lazy range that involves a lambda that allocates a closure. Of course, or a @nogc range that allocates with malloc or eagerly steps through the entire range. Anyhow I just mentioned it because it's the best form of automatic checking that we have (what the OP was asking for) and in many cases when an algorithm can't be @nogc it does allocate somewhere which is a red flag.
Re: countUntil to print all the index of a given string.
On Sunday, February 25, 2018 01:49:05 Seb via Digitalmars-d-learn wrote: > On Tuesday, 20 February 2018 at 08:44:37 UTC, aberba wrote: > > On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: > >> On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: > >>> [...] > >> > >> Just thought of a much better/simpler solution for that last > >> case that also doesn't force you to read all data (which might > >> > >> be impossible when dealing with infinite ranges): > >> import std.range; > >> import std.algorithm; > >> > >> a[] > >> > >> .enumerate // get tuples (index, > >> > >> value) > >> > >> .filter!(t => t[1] == "Test2") // keep only if value == > >> > >> "Test2" > >> > >> .map!(t => t[0]) // keep only the index > >> > >> part > >> > >> .writeln; > >> > >> Completely lazy. > > > > How does one detect an operation as lazy or not? Is the some > > compile-time or runtime check for that? > > > > My guess is by referring to the docs function signature. > > While it's not a replacement for checking the code manually, > @nogc helps a lot: That doesn't actually tell you whether the range is lazy. It just tells you whether any allocations may occur. If any exceptions could be thrown, then a lazy solution can't be @nogc (something that's often the case with strings thanks to auto-decoding and UTFExceptions), and a solution could be eager without allocating if the result doesn't require any allocation. Also, you could have a lazy range that involves a lambda that allocates a closure. So, yeah, a lot of the time, @nogc means that the range is lazy, but it doesn't guarantee it, and not being able to be @nogc doesn't mean that it's eager. So, I'd argue that while @nogc gives you a clue, it's ultimately a pretty poor way to try and figure out whether a range is lazy or not. All it really tells you is whether it's guaranteed that no allocations will occur on the GC heap. - Jonathan M Davis
Re: countUntil to print all the index of a given string.
On Tuesday, 20 February 2018 at 08:44:37 UTC, aberba wrote: On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: [...] Just thought of a much better/simpler solution for that last case that also doesn't force you to read all data (which might be impossible when dealing with infinite ranges): import std.range; import std.algorithm; a[] .enumerate // get tuples (index, value) .filter!(t => t[1] == "Test2") // keep only if value == "Test2" .map!(t => t[0]) // keep only the index part .writeln; Completely lazy. How does one detect an operation as lazy or not? Is the some compile-time or runtime check for that? My guess is by referring to the docs function signature. While it's not a replacement for checking the code manually, @nogc helps a lot: --- void main() @nogc { import std.container, std.stdio; auto a = Array!string("Test1", "Test2", "Test3", "Test1", "Test2"); import std.algorithm, std.range; auto r = a[].enumerate.filter!(t => t[1] == "Test2").map!(t => t[0]); debug r.writeln; // std.stdio.writeln allocates at the moment } --- https://run.dlang.io/is/Fo32sN
Re: countUntil to print all the index of a given string.
On Tuesday, 20 February 2018 at 08:50:27 UTC, Jonathan M Davis wrote: On Tuesday, February 20, 2018 08:44:37 aberba via Digitalmars-d-learn wrote: On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: > On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: >> [...] > > Just thought of a much better/simpler solution for that last > case that also doesn't force you to read all data (which > might > > be impossible when dealing with infinite ranges): > import std.range; > import std.algorithm; > > a[] > > .enumerate // get tuples (index, > > value) > > .filter!(t => t[1] == "Test2") // keep only if value > == > > "Test2" > > .map!(t => t[0]) // keep only the index > > part > > .writeln; > > Completely lazy. How does one detect an operation as lazy or not? Is the some compile-time or runtime check for that? My guess is by referring to the docs function signature. You have to read the docs or read the source code, though in general, functions that return a range type that wraps the original range tend to be lazy, whereas if a function returns the original range type or an array, then it's clearly not lazy. - Jonathan M Davis Hi All, Thank you very much, the provide solution work's for the given example, so how can we achieve the same for the below code import std.stdio; import std.container; import std.algorithm; void main () { auto a = Array!string("Test1", "Test2", "Test3", "Test1", "Test2"); auto b = Array!string("Test1", "Test2", "Test3"); foreach(i; b[]) { writeln(SList!int(a[].countUntil(i))[]); } } Output [0] [1] [2] Required [0,3] [1,4] [2] From, Vino.B
Re: countUntil to print all the index of a given string.
On Tuesday, February 20, 2018 08:44:37 aberba via Digitalmars-d-learn wrote: > On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: > > On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: > >> [...] > > > > Just thought of a much better/simpler solution for that last > > case that also doesn't force you to read all data (which might > > > > be impossible when dealing with infinite ranges): > > import std.range; > > import std.algorithm; > > > > a[] > > > > .enumerate // get tuples (index, > > > > value) > > > > .filter!(t => t[1] == "Test2") // keep only if value == > > > > "Test2" > > > > .map!(t => t[0]) // keep only the index > > > > part > > > > .writeln; > > > > Completely lazy. > > How does one detect an operation as lazy or not? Is the some > compile-time or runtime check for that? > > My guess is by referring to the docs function signature. You have to read the docs or read the source code, though in general, functions that return a range type that wraps the original range tend to be lazy, whereas if a function returns the original range type or an array, then it's clearly not lazy. - Jonathan M Davis
Re: countUntil to print all the index of a given string.
On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: [...] Just thought of a much better/simpler solution for that last case that also doesn't force you to read all data (which might be impossible when dealing with infinite ranges): import std.range; import std.algorithm; a[] .enumerate // get tuples (index, value) .filter!(t => t[1] == "Test2") // keep only if value == "Test2" .map!(t => t[0]) // keep only the index part .writeln; Completely lazy. How does one detect an operation as lazy or not? Is the some compile-time or runtime check for that? My guess is by referring to the docs function signature.
Re: countUntil to print all the index of a given string.
On Sunday, 18 February 2018 at 15:23:14 UTC, Cym13 wrote: On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: [...] Just thought of a much better/simpler solution for that last case that also doesn't force you to read all data (which might be impossible when dealing with infinite ranges): import std.range; import std.algorithm; a[] .enumerate // get tuples (index, value) .filter!(t => t[1] == "Test2") // keep only if value == "Test2" .map!(t => t[0]) // keep only the index part .writeln; Completely lazy. A nice example of how D's multiparadigm programming model allows the utilisation of algorithms that can scale to process massive datasets. There is an article in there somewhere ;-)
Re: countUntil to print all the index of a given string.
On Sunday, 18 February 2018 at 14:48:59 UTC, Cym13 wrote: [...] Just thought of a much better/simpler solution for that last case that also doesn't force you to read all data (which might be impossible when dealing with infinite ranges): import std.range; import std.algorithm; a[] .enumerate // get tuples (index, value) .filter!(t => t[1] == "Test2") // keep only if value == "Test2" .map!(t => t[0]) // keep only the index part .writeln; Completely lazy.
Re: countUntil to print all the index of a given string.
On Sunday, 18 February 2018 at 11:55:37 UTC, Vino wrote: Hi All, Request your help on printing the all index of an array element , eg; the below code prints the index of the string "Test2" as [1], but the string "Test2" is present 2 times at index 1 and 4, so how do I print all the index of a given string. import std.stdio; import std.container; import std.algorithm; void main () { auto a = Array!string("Test1", "Test2", "Test3", "Test1", "Test2"); writeln(SList!int(a[].countUntil("Test2"))[]); } Output [1] Expected [1, 4] From, Vino.B countUntil is good when you want to avoid having to look at all your data, but in this case I don't think it's the best solution. You could do a loop storing each index and then restart your countUntil from there, but quite frankly it would be easier to just loop over the array at that point: ulong[] result; for (ulong index=0 ; indexHowever, if you want a more streamlined, functionnal solution, you can go all the way and avoid all explicit loops and intermediate variables using fold: import std.range: enumerate; import std.algorithm: fold; a[] .enumerate .fold!((a, b) => b[1] == "Test2" ? a ~ b[0] : a)(cast(ulong[])[]) .writeln;
countUntil to print all the index of a given string.
Hi All, Request your help on printing the all index of an array element , eg; the below code prints the index of the string "Test2" as [1], but the string "Test2" is present 2 times at index 1 and 4, so how do I print all the index of a given string. import std.stdio; import std.container; import std.algorithm; void main () { auto a = Array!string("Test1", "Test2", "Test3", "Test1", "Test2"); writeln(SList!int(a[].countUntil("Test2"))[]); } Output [1] Expected [1, 4] From, Vino.B