digitalmars.D - rectifiedIndexOf()
- Salih Dincer (59/59) May 04 2023 It has a traditional very beautiful function: indexOf() but it
- Basile B. (28/48) May 04 2023 As often in D you can use a struct to help:
- Salih Dincer (44/47) May 05 2023 I haven't seen such an accurate solution from those who replied
- apz28 (3/31) May 05 2023 Try below
- Quirin Schroll (8/10) May 06 2023 That is bad design. It should return an optional type or
- Salih Dincer (15/25) May 06 2023 In fact, there is worse! The intent is to prevent leaking
- Quirin Schroll (15/42) May 12 2023 I guess the reason why something that is declared in the
It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'... ```d void main() { enum chr = 'c'; auto arr = "dlang".dup; if(auto res = arr.indexOf(chr)) { assert(arr[res] == chr); // core.exception.ArrayIndexError } } ``` When you try to solve the problem with boolean logic, res is now a bool. ```d void main() { enum chr = 'd'; auto arr = "dlang".dup; if(auto res = arr.indexOf(chr) > -1) { assert(arr[res] == chr); // core.exception.AssertError } } ``` We can solve this problem with an alternativeIndexOf, but we're sailing another problem: Rectified Index... ```d import std.stdio; void main() { enum chr = 'c'; auto arr = "dlang".dup; if(auto res = arr.rectifiedIndexOf(chr)) { assert(arr[res - 1] == chr); res.writefln!"[ --> %s ]"; } else writeln("Not found!"); } auto rectifiedIndexOf(A)(A[] arr, A key) { size_t i = 1; while(i <= arr.length) { if(arr[i - 1] == key) { return i; } else i++; } return 0; } ``` So now that we've broken the traditional index approach, you need to consider this (res - 1) in your code. SDB 79
May 04 2023
On Friday, 5 May 2023 at 00:19:01 UTC, Salih Dincer wrote:It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'... ```d void main() { enum chr = 'c'; auto arr = "dlang".dup; if(auto res = arr.indexOf(chr)) { assert(arr[res] == chr); // core.exception.ArrayIndexError } } ``` When you try to solve the problem with boolean logic, res is now a bool. [...] So now that we've broken the traditional index approach, you need to consider this (res - 1) in your code. SDB 79As often in D you can use a struct to help: ```d auto toBool(ptrdiff_t t) { struct ToBool { ptrdiff_t value; alias value this; bool opCast(T : bool)() { return value != -1; } } return ToBool(t); } void main() { enum chr = 'l'; auto arr = "dlang".dup; if (auto res = arr.indexOf(chr).toBool()) { assert(res == 1); } } ``` `opCast` is used for the `if` condition and the original value for reading back in the array, via `alias this`.
May 04 2023
On Friday, 5 May 2023 at 02:43:15 UTC, Basile B. wrote:As often in D you can use a struct to help... `opCast` is used for the `if` condition and the original value for reading back in the array, via `alias this`.I haven't seen such an accurate solution from those who replied to me until now. Thanks a lot because very works! ```d auto toBool(ptrdiff_t t) { struct ToBool { ptrdiff_t value; alias value this; bool opCast(T : bool)() { return value != -1; } } return ToBool(t); } void find(char chr) { import std.stdio, std.range, std.string : indexOf; if(auto res = arr.indexOf(chr).toBool) { arr.writeln; assert(arr[res] == chr); ' '.repeat(res).writeln("^--found!"); } else { chr.writeln(" character not found!"); } } auto arr = "dlang".dup; void main() { foreach(chr; "cad") chr.find(); } /* Prints: c character not found! dlang ^--found! dlang ^--found! */ ``` SDB 79
May 05 2023
On Friday, 5 May 2023 at 14:50:45 UTC, Salih Dincer wrote:On Friday, 5 May 2023 at 02:43:15 UTC, Basile B. wrote:Or as below struct IndexOfResult { ptrdiff_t value; alias value this; bool opCast(T : bool)() const nogc pure safe { return value >= 0; } } void main() { import std.string : indexOf; import std.stdio : writeln, writefln; enum chr = 'a'; enum arr = "dlang"; if (auto res = IndexOfResult(arr.indexOf(chr))) { assert(arr[res] == chr); res.writefln!"[ --> %s ]"; } else writeln("Not found!"); }As often in D you can use a struct to help... `opCast` is used for the `if` condition and the original value for reading back in the array, via `alias this`.
May 05 2023
On Friday, 5 May 2023 at 16:51:25 UTC, apz28 wrote:On Friday, 5 May 2023 at 14:50:45 UTC, Salih Dincer wrote:Yeah IndexOfResult is a much better name... but you should not change the comparison operator... in theory using `!=-1` allows `-2`, ie `size_t.max-1` to be a valid result.On Friday, 5 May 2023 at 02:43:15 UTC, Basile B. wrote:Or as below struct IndexOfResult { ptrdiff_t value; alias value this; bool opCast(T : bool)() const nogc pure safe { return value >= 0; } } void main() { import std.string : indexOf; import std.stdio : writeln, writefln; enum chr = 'a'; enum arr = "dlang"; if (auto res = IndexOfResult(arr.indexOf(chr))) { assert(arr[res] == chr); res.writefln!"[ --> %s ]"; } else writeln("Not found!"); }As often in D you can use a struct to help... `opCast` is used for the `if` condition and the original value for reading back in the array, via `alias this`.
May 05 2023
On Friday, 5 May 2023 at 00:19:01 UTC, Salih Dincer wrote:It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'... ```d void main() { enum chr = 'c'; auto arr = "dlang".dup; if(auto res = arr.indexOf(chr)) { assert(arr[res] == chr); // core.exception.ArrayIndexError } } ``` When you try to solve the problem with boolean logic, res is now a bool. ```d void main() { enum chr = 'd'; auto arr = "dlang".dup; if(auto res = arr.indexOf(chr) > -1) { assert(arr[res] == chr); // core.exception.AssertError } } ```Try below https://gist.github.com/run-dlang/316a1b9df1c14dade4c5ff13c927cc84
May 05 2023
On Friday, 5 May 2023 at 00:19:01 UTC, Salih Dincer wrote:It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'...That is bad design. It should return an optional type or something like that, but D doesn’t have those. C++ has a lot of similar functions and I guess that was one reason why C++17 introduced an *init-statment* to `if`. D could do the same. ```d if (auto index = arr.indexOf('c'); index >= 0) … ```
May 06 2023
On Saturday, 6 May 2023 at 16:39:13 UTC, Quirin Schroll wrote:On Friday, 5 May 2023 at 00:19:01 UTC, Salih Dincer wrote:In fact, there is worse! The intent is to prevent leaking outside the scope of if-else. But it doesn't work in the else block and we get the error undefined identifier `num`. ```d if(auto num = imported!"std.random".uniform!int.max % 2) { assert(num > 0); } else { //assert(num == 0); } ``` I would like these issues to be resolved, but we spend our energy on more difficult things! SDB 79It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'...That is bad design. It should return an optional type or something like that, but D doesn’t have those. C++ has a lot of similar functions and I guess that was one reason why C++17 introduced an *init-statment* to `if`. D could do the same. ```d if (auto index = arr.indexOf('c'); index >= 0) … ```
May 06 2023
On Saturday, 6 May 2023 at 18:58:54 UTC, Salih Dincer wrote:On Saturday, 6 May 2023 at 16:39:13 UTC, Quirin Schroll wrote:I guess the reason why something that is declared in the condition is scoped to the “then” part and not visible in the “else” part is that if something evaluates to `false`, usually it’s not interesting. Something that evaluates to `false` is a `bool` that’s `false`, a number that’s `0`, or a pointer or class handle or whatever reference type that holds no interesting state. A user-defined type evaluates to `false` and has an interesting value is really bad design. However, if you do C++’s `if` with initialization and condition separately, you can handle the “uninteresting `false`” value in the “then” branch and do the interesting work in the “else” branch. For that reason, something declared in the *init-statement* of an `if` should be visible in the “else” branch.On Friday, 5 May 2023 at 00:19:01 UTC, Salih Dincer wrote:In fact, there is worse! The intent is to prevent leaking outside the scope of if-else. But it doesn't work in the else block and we get the error undefined identifier `num`. ```d if(auto num = imported!"std.random".uniform!int.max % 2) { assert(num > 0); } else { //assert(num == 0); } ``` I would like these issues to be resolved, but we spend our energy on more difficult things!It has a traditional very beautiful function: indexOf() but it has an important problem: returns -1 when it can't find 'c'...That is bad design. It should return an optional type or something like that, but D doesn’t have those. C++ has a lot of similar functions and I guess that was one reason why C++17 introduced an *init-statment* to `if`. D could do the same. ```d if (auto index = arr.indexOf('c'); index >= 0) … ```
May 12 2023