| Thread overview | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
January 22, 2015 Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
I want to define alphanumeric characters in an easy way. Something like that: char[] arr = ['a'..'z', 'A'..'Z', '0'..'9']; Though above example doesn't work. Is there any easy way to do this? I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand. | ||||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to tcak | On Thursday, 22 January 2015 at 05:56:40 UTC, tcak wrote:
> I want to define alphanumeric characters in an easy way. Something like that:
>
> char[] arr = ['a'..'z', 'A'..'Z', '0'..'9'];
>
> Though above example doesn't work. Is there any easy way to do this?
>
> I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand.
This is interesting, I think this syntax would be pretty cool if it did work (I think it would work in foreach loops... at least it does with integers).
Anyway, what you could do is define a static struct with slicing overloaded for chars, and have it return slices of a master char array or a generating function. Assume you called the struct C, then your char array declaration could looks something like
join (C['a'..'z'], C['A'..'Z'], C['0'..'9'])
It is a bit of up-front work, though it is maintainable. I'm also curious if there is indeed an easier way.
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to tcak | On Thursday, 22 January 2015 at 05:56:40 UTC, tcak wrote:
> I want to define alphanumeric characters in an easy way. Something like that:
>
> char[] arr = ['a'..'z', 'A'..'Z', '0'..'9'];
>
> Though above example doesn't work. Is there any easy way to do this?
>
> I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand.
There are convenient constants defined in std.ascii.
import std.ascii;
string arr = lowercase ~ uppercase ~ digits;
// also 'std.ascii.letters' gives ('A' .. 'Z' ~ 'a' .. 'z')
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to anony | On Thursday, 22 January 2015 at 07:29:05 UTC, anony wrote:
> On Thursday, 22 January 2015 at 05:56:40 UTC, tcak wrote:
>> I want to define alphanumeric characters in an easy way. Something like that:
>>
>> char[] arr = ['a'..'z', 'A'..'Z', '0'..'9'];
>>
>> Though above example doesn't work. Is there any easy way to do this?
>>
>> I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand.
>
> There are convenient constants defined in std.ascii.
>
> import std.ascii;
> string arr = lowercase ~ uppercase ~ digits;
>
> // also 'std.ascii.letters' gives ('A' .. 'Z' ~ 'a' .. 'z')
Well, that's just disguising what we can't do.
D has alot of compile time structures, even much complex than what I asked. So, this type of thing should be doable for immutable arrays.
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to tcak | tcak:
> Well, that's just disguising what we can't do.
When the a..b syntax was added to foreach() someone criticized that syntax saing it's a "one trick pony", and indeed I don't know why Walter didn't make it a little more first-class.
But note that in D the a..b ranges are always open on the right, so 'a'..'z' can't include the 'z'.
What do you think of this?
import std.stdio, std.range, std.algorithm, std.array;
auto charInterval(in char a, in char b) pure nothrow @safe @nogc {
return iota(a, b + 1).map!(i => cast(char)i);
}
void main() @safe {
char[] arr = chain(charInterval('a', 'z'),
charInterval('A', 'Z'),
charInterval('0', '9')).array;
arr.writeln;
}
charInterval can of course become eager too, so you just need ~ to concatenate the results:
import std.stdio, std.range, std.algorithm, std.array;
char[] charInterval(in char a, in char b) pure nothrow @safe {
return iota(a, b + 1).map!(i => cast(char)i).array;
}
void main() @safe {
char[] arr = charInterval('a', 'z') ~
charInterval('A', 'Z') ~
charInterval('0', '9');
arr.writeln;
}
Bye,
bearophile
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to tcak | On Thursday, January 22, 2015 05:56:39 tcak via Digitalmars-d-learn wrote:
> I want to define alphanumeric characters in an easy way. Something like that:
>
> char[] arr = ['a'..'z', 'A'..'Z', '0'..'9'];
>
> Though above example doesn't work. Is there any easy way to do this?
>
> I am trying to do something like EBNF definitions. So, I do not want to use loops, or define every single thing one by one by hand.
std.range.iota is what's used to creat ranges of values, and std.array.array can be used to convert a range to an array. So, the functionality si in the standard library, even if it's not quite as clean as you might like it to be. e.g.
import std.range;
alias uiota = iota!(ubyte, ubyte);
auto r = chain(uiota('a', 'z'), uiota('A', 'Z'), uiota('0', '9'));
auto arr = cast(char[])array(r);
And actually, it's worse with chars than it would be with integers, because for some reason, iota doesn't seem to want to operate directly on char, but presumably that could be fixed, which would help clean up the code. But regardless, the functionality is there without needing to add it to the language, much as it might be nice to have it in the language where it would look a bit cleaner.
- Jonathan M Davis
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to tcak | On Thursday, 22 January 2015 at 09:26:21 UTC, tcak wrote:
>> There are convenient constants defined in std.ascii.
>>
>> import std.ascii;
>> string arr = lowercase ~ uppercase ~ digits;
>>
>> // also 'std.ascii.letters' gives ('A' .. 'Z' ~ 'a' .. 'z')
>
> Well, that's just disguising what we can't do.
>
> D has alot of compile time structures, even much complex than what I asked. So, this type of thing should be doable for immutable arrays.
If you declare the string as immutable, the concatenation will be done at compile time.
| |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis: > auto r = chain(uiota('a', 'z'), uiota('A', 'Z'), uiota('0', '9')); Those ranges are probably open on the right. In Bugzilla I have asked for the syntax iota!"[]"(a, b) to change how the extrema are handled, modelled on std.random.uniform syntax. --------------- Kagamin: > If you declare the string as immutable, the concatenation will be done at compile time. In function-scope I think you need enum. Bye, bearophile | |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to bearophile | On Thursday, January 22, 2015 10:42:59 bearophile via Digitalmars-d-learn wrote: > Jonathan M Davis: > > > auto r = chain(uiota('a', 'z'), uiota('A', 'Z'), uiota('0', > > '9')); > > Those ranges are probably open on the right. They probably are actually, since open on the right is usually how things are done, but that's easy fixed with some +1's. > Kagamin: > > > If you declare the string as immutable, the concatenation will be done at compile time. > > In function-scope I think you need enum. Yeah. immutable has nothing to do with compile time, though if you're talking about concatenating constants, there's a decent chance that they'd be optimized so that no concatenation occurs at runtime. However, to force anything to happen at compile time, you need to be initializing something that _has_ to be initialized at compile time (enum, static variable, direct initialization of member variable, etc.). If the compiler ever has a choice, it won't do it aside from built-in stuff that it understands well enough to translate as an optimization. - Jonathan M Davis | |||
January 22, 2015 Re: Defining a static array with values in a range | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Jonathan M Davis:
> but that's easy fixed with some +1's.
But the +1 changes the char to an int.
Bye,
bearophile
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply