What property of a container (type) T
enables iteration as
foreach (k, v; T.init)
{
...
}
? I thought it sufficed to define T.byKeyValue
but its presence seem to have no effect.
Thread overview | |||||||
---|---|---|---|---|---|---|---|
|
October 24, 2022 Supporting foreach (k, v; T.init) for a user-defined (container) type | ||||
---|---|---|---|---|
| ||||
What property of a container (type)
? I thought it sufficed to define |
October 25, 2022 Re: Supporting foreach (k, v; T.init) for a user-defined (container) type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | From there down: https://dlang.org/spec/statement.html#foreach_over_struct_and_classes |
October 24, 2022 Re: Supporting foreach (k, v; T.init) for a user-defined (container) type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On Mon, Oct 24, 2022 at 09:26:14PM +0000, Per Nordlöw via Digitalmars-d-learn wrote: > What property of a container (type) `T` enables iteration as > > ```d > foreach (k, v; T.init) > { > ... > } > ``` > > ? I thought it sufficed to define `T.byKeyValue` but its presence seem to have no effect. You want opApply. Full working example: ------ struct A { static int[string] impl; static this() { impl = [ "a": 1, "b": 2, ]; } int opApply(scope int delegate(string a, int b) dg) { foreach (k, v; impl) { auto r = dg(k, v); if (r) return r; } return 0; } } void main() { import std; A a; foreach (k, v; a) { writefln("%s -> %s", k, v); } } ------ T -- Computers shouldn't beep through the keyhole. |
October 24, 2022 Re: Supporting foreach (k, v; T.init) for a user-defined (container) type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Per Nordlöw | On 10/24/22 14:26, Per Nordlöw wrote:
> What property of a container (type) `T` enables iteration as
>
> ```d
> foreach (k, v; T.init)
> {
> ...
> }
> ```
>
> ? I thought it sufficed to define `T.byKeyValue` but its presence seem to have no effect.
Another option is to use range functions where front() returns a Tuple. We have an esoteric feature where a tuple expands automatically in foreach loops:
import std.typecons : tuple;
import std.conv : to;
import std.stdio : writeln;
import std.range : take;
struct S {
size_t count;
bool empty = false;
auto front() {
const key = count;
const value = key.to!string;
return tuple(key, value); // <-- HERE
}
void popFront() {
++count;
}
}
void main() {
foreach (k, v; S.init.take(10))
{
writeln(k, ": ", v);
}
}
Ali
|
October 25, 2022 Re: Supporting foreach (k, v; T.init) for a user-defined (container) type | ||||
---|---|---|---|---|
| ||||
Posted in reply to Ali Çehreli | On Monday, 24 October 2022 at 21:52:18 UTC, Ali Çehreli wrote:
> On 10/24/22 14:26, Per Nordlöw wrote:
>> [...]
>
> Another option is to use range functions where front() returns a Tuple. We have an esoteric feature where a tuple expands automatically in foreach loops:
>
> import std.typecons : tuple;
> import std.conv : to;
> import std.stdio : writeln;
> import std.range : take;
>
> struct S {
> size_t count;
> bool empty = false;
>
> auto front() {
> const key = count;
> const value = key.to!string;
> return tuple(key, value); // <-- HERE
> }
>
> void popFront() {
> ++count;
> }
> }
>
> void main() {
> foreach (k, v; S.init.take(10))
> {
> writeln(k, ": ", v);
> }
> }
>
> Ali
I didn't know about that esoteric feature. like this approach
|