Thread overview | |||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 25, 2018 iota to array | ||||
---|---|---|---|---|
| ||||
Hi. Anyone know whether something like this is possible? I've tried various conversions/casts, but no luck yet. Essentially, I want to cast the result set of the iota to an array, during initialisation of the variable. no, I don't want to use 'auto'. I want an array object ;-) -------------- module test; import std.stdio; import std.range : iota; void main() { int[] intArr = iota(1, 11); // 1..10 double[] doubleArr = iota(1.0, 11.0); // 1.0..10.0 char[] charArr = iota('a', '{'); // a..z } ------------- |
February 24, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sunday, February 25, 2018 05:24:54 psychoticRabbit via Digitalmars-d- learn wrote:
> Hi. Anyone know whether something like this is possible?
>
> I've tried various conversions/casts, but no luck yet.
>
> Essentially, I want to cast the result set of the iota to an array, during initialisation of the variable.
>
> no, I don't want to use 'auto'. I want an array object ;-)
>
> --------------
> module test;
>
> import std.stdio;
> import std.range : iota;
>
> void main()
> {
> int[] intArr = iota(1, 11); // 1..10
> double[] doubleArr = iota(1.0, 11.0); // 1.0..10.0
> char[] charArr = iota('a', '{'); // a..z
> }
> -------------
As with any range, you can call std.array.array to convert it to an array. So, you can have:
int[] intArr = iota(1, 11).array();
or more idiomatically:
auto intArr = iota(1, 11).array();
And auto does _not_ mean that it's not an array. It just means that the type is inferred, which is pretty much required when you're dealing with ranges, because the range types get a bit disgusting to type even if they're not Voldemort types, and if they are Voldemort types, then you pretty much have to use auto, since you can't refer to the type by name. But in general, even when you know exactly what the type is, it's good practice to use auto, since then you're avoiding repeating the type, and it makes it so that you don't have to change as much code later if the type of the variable changes. The classic example of where auto should be used when you know exactly what the type is would be with new. e.g.
MyClass c = new MyClass;
is unnecessarily redundant, and
auto c = new MyClass;
is preferred. In your case, providing the type isn't redundant, since the type isn't listed on the right-hand side of the expression, but it's still unnecessary to list the type, so auto is generally preferred - though obviously, if you really want to be explicit about the types everywhere, there's nothing stopping you from doing so. It just makes the code harder to maintain if the type ever changes.
- Jonathan M Davis
|
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sunday, 25 February 2018 at 05:24:54 UTC, psychoticRabbit wrote: > Hi. Anyone know whether something like this is possible? > > I've tried various conversions/casts, but no luck yet. > > Essentially, I want to cast the result set of the iota to an array, during initialisation of the variable. You can't do that, because iota is a range and only exists as a range struct on the stack. Think about it as a struct with three variables (start, end, stepSize) - not as an array. Of course, iota is a lot smarter than that as things like `10.iota[3 .. $]` or `3 in 10.iota` work, but it's important to notice that e.g. `iota[1 .. 2]` just returns a new range object. No GC allocation happens here and "the array" never actually exists in memory. > no, I don't want to use 'auto'. I want an array object ;-) This has nothing to do with auto. Auto is just a filler word for the compiler that says: "whatever is the type of the declaration, use this as the type". In other words, the compiler does this automatically for you: --- typeof(10.iota) r = 10.iota; --- Anyhow it looks like what you want to do is to __allocate__ an array. You can do so with std.array.array. --- import std.array, std.range; void main() { int[] arr = 10.iota.array; } --- https://run.dlang.io/is/kKSzjH Again, notice that the actual implementation of array is this (in the non-optimized case): --- auto array(Range)(Range r) { auto a = appender!(E[])(); // <- allocation happens in the appender foreach (e; r) a.put(e); return a.data; } --- (without constraints for simplicity) Of course, Phobos has a more sophisticated version of std.array.array, but it's basically like this: https://github.com/dlang/phobos/blob/master/std/array.d#L97 > -------------- > module test; > > import std.stdio; > import std.range : iota; > > void main() > { > int[] intArr = iota(1, 11); // 1..10 > double[] doubleArr = iota(1.0, 11.0); // 1.0..10.0 > char[] charArr = iota('a', '{'); // a..z > } > ------------- |
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 25 February 2018 at 05:40:19 UTC, Jonathan M Davis wrote: > > int[] intArr = iota(1, 11).array(); > > > - Jonathan M Davis thanks! oh man. It's so easy to do stuff in D ;-) But this leads me to a new problem now. When I run my code below, I get ints printed instead of doubles?? --------------------- module test; import std.stdio : writeln; import std.traits : isArray; import std.array : array; import std.range : iota; void main() { int[] intArr = iota(1, 11).array(); // 1..10 double[] doubleArr = iota(1.0, 11.0).array(); // 1.0..10.0 char[] charArr = iota('a', '{').array(); // a..z printArray(intArr); printArray(doubleArr); // why is it printing ints instead of doubles?? printArray(charArr); } void printArray(T)(const ref T[] a) if (isArray!(T[])) { foreach(t; a) writeln(t); } --------------------------------- |
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sunday, 25 February 2018 at 06:22:03 UTC, psychoticRabbit wrote: > On Sunday, 25 February 2018 at 05:40:19 UTC, Jonathan M Davis wrote: >> >> int[] intArr = iota(1, 11).array(); >> >> >> - Jonathan M Davis > > thanks! > > oh man. It's so easy to do stuff in D ;-) > > But this leads me to a new problem now. > > When I run my code below, I get ints printed instead of doubles?? > > --------------------- > module test; > > import std.stdio : writeln; > import std.traits : isArray; > import std.array : array; > import std.range : iota; > > > void main() > { > int[] intArr = iota(1, 11).array(); // 1..10 > double[] doubleArr = iota(1.0, 11.0).array(); // 1.0..10.0 > char[] charArr = iota('a', '{').array(); // a..z > > printArray(intArr); > printArray(doubleArr); // why is it printing ints instead of doubles?? > printArray(charArr); > } > > void printArray(T)(const ref T[] a) if (isArray!(T[])) > { > foreach(t; a) > writeln(t); > } > > --------------------------------- 2 Things: 1. You can just use writeln to directly print Arrays. If you want a specific format for the array you can use writef/writefln 2. By default, writeln will print [1, 2, 3] when your array contains [1.0, 2.0, 3.0], since thats considered neater. You can use writefln to address that. You can see this here: https://run.dlang.io/is/bNxIsH You can read more about format strings here: https://dlang.org/phobos/std_format.html#format-string |
February 24, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sunday, February 25, 2018 06:22:03 psychoticRabbit via Digitalmars-d- learn wrote:
> On Sunday, 25 February 2018 at 05:40:19 UTC, Jonathan M Davis
>
> wrote:
> > int[] intArr = iota(1, 11).array();
> >
> > - Jonathan M Davis
>
> thanks!
>
> oh man. It's so easy to do stuff in D ;-)
>
> But this leads me to a new problem now.
>
> When I run my code below, I get ints printed instead of doubles??
>
> ---------------------
> module test;
>
> import std.stdio : writeln;
> import std.traits : isArray;
> import std.array : array;
> import std.range : iota;
>
>
> void main()
> {
> int[] intArr = iota(1, 11).array(); // 1..10
> double[] doubleArr = iota(1.0, 11.0).array(); // 1.0..10.0
> char[] charArr = iota('a', '{').array(); // a..z
>
> printArray(intArr);
> printArray(doubleArr); // why is it printing ints instead of
> doubles??
> printArray(charArr);
> }
>
> void printArray(T)(const ref T[] a) if (isArray!(T[]))
> {
> foreach(t; a)
> writeln(t);
> }
>
> ---------------------------------
It's not printing ints. It's printing doubles. It's just that all of the doubles have nothing to the right of the decimal point, so they don't get printed with a decimal point. If you did something like start with 1.1, then you'd see decimal points, because there would be data to the right of the decimal point. The same thing happens if you do
writeln(1.0);
as opposed to something like
writeln(1.3);
BTW, you can just call writeln on the array directly, and then you'll get something like
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
- Jonathan M Davis
|
February 24, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sun, Feb 25, 2018 at 06:22:03AM +0000, psychoticRabbit via Digitalmars-d-learn wrote: [..] > printArray(doubleArr); // why is it printing ints instead of doubles?? [...] > void printArray(T)(const ref T[] a) if (isArray!(T[])) > { > foreach(t; a) > writeln(t); Try: writefln("%.3f", t); instead. > } > > --------------------------------- T -- Dogs have owners ... cats have staff. -- Krista Casada |
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | On Sunday, 25 February 2018 at 06:35:07 UTC, Jonathan M Davis wrote:
>
> It's not printing ints. It's printing doubles. It's just that all of the doubles have nothing to the right of the decimal point, so they don't get printed with a decimal point. If you did something like start with 1.1, then you'd see decimal points, because there would be data to the right of the decimal point. The same thing happens if you do
>
> writeln(1.0);
>
> as opposed to something like
>
> writeln(1.3);
>
thanks.
But umm.... what happended to the principle of least astonishment?
writeln(1.1); (prints 1.1)
whereas..
writeln(1.0); (prints 1)
I don't get it. Cause it's 'nicer'??
I ended up having to work around this..like this:
-------
void printArray(T)(const ref T[] a) if (isArray!(T[]))
{
if( isFloatingPoint!T)
foreach(t; a) writefln("%.1f", t);
else
foreach(t; a) writefln("%s", t);
}
-------
|
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to psychoticRabbit | On Sunday, 25 February 2018 at 08:08:30 UTC, psychoticRabbit wrote:
>
>
> But umm.... what happended to the principle of least astonishment?
>
> writeln(1.1); (prints 1.1)
> whereas..
> writeln(1.0); (prints 1)
>
> I don't get it. Cause it's 'nicer'??
>
Because writeln(someFloat) is equivalent to writefln("%g", someFloat). And according to printf specification, "trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit"
|
February 25, 2018 Re: iota to array | ||||
---|---|---|---|---|
| ||||
Posted in reply to rumbu | On Sunday, 25 February 2018 at 08:46:19 UTC, rumbu wrote:
> On Sunday, 25 February 2018 at 08:08:30 UTC, psychoticRabbit wrote:
>>
>>
>> But umm.... what happended to the principle of least astonishment?
>>
>> writeln(1.1); (prints 1.1)
>> whereas..
>> writeln(1.0); (prints 1)
>>
>> I don't get it. Cause it's 'nicer'??
>>
>
> Because writeln(someFloat) is equivalent to writefln("%g", someFloat). And according to printf specification, "trailing zeros are removed from the fractional part of the result; a decimal point appears only if it is followed by at least one digit"
oh. that explains it.
I would have preffered it defaulted java style ;-)
System.out.println(1.0); // i.e. it prints 'what I told it to print'.
|
Copyright © 1999-2021 by the D Language Foundation