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 79
As 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









Basile B. <b2.temp gmx.com> 