Jump to page: 1 2
Thread overview
Dynamic array and foreach loop
Aug 08, 2015
Binarydepth
Aug 08, 2015
Binarydepth
Aug 08, 2015
DarthCthulhu
Aug 08, 2015
Binarydepth
Aug 08, 2015
Binarydepth
Aug 09, 2015
Jay Norwood
Aug 09, 2015
Binarydepth
Aug 09, 2015
Alex Parrill
Aug 09, 2015
Jay Norwood
Aug 09, 2015
Binarydepth
Aug 09, 2015
Jay Norwood
August 08, 2015
I'm writing a program that rotates numbers then asks the user if a new set of numbers should be rotated. I'm having trouble using a Foreach loop to fill a dynamic array with the elements to be rotated.

Here's my code, I add a TAB when a loop is inside a loop and and do that too to the statements inside and to IF's also.

import std.stdio;

/*Input : Quantity of elements, elements y positions to be rotated*/
/*Output : Elements rotated as requested*/
void main()        {
int liEle, liCount, liRot, liAcc;
int[] liaOrig, liaFinal;
immutable kArr=50;
/*Variables : Quantity of elements to be used, Counter variable for loops,
Array for original sequence, Array for final sequence, Variable for positions to rotate and
Action counter variable.

*/
char lcRot;//Variable for options

do	{//Complete program. Also runs when an other sequence is to be used

        do	{//Validation loop for the array. Must be positive


		 write ("How many elements need to be used? ");
		 readf(" %d", &liEle);
		        if(liEle<2)
			        write("Must be a number greater than 1\n");
	}while(liEle<2 || liEle>kArr);
	liaOrig.length = liEle;
	liaFinal.length = liEle;
	foreach(num; liaOrig[0..$])	{//Data input loop

		write("Input the element : ", num+1, " ");
		readf(" %d", &liaOrig[num]);
	}

	do	{
	        do	{
		        write("How many positions do you wish to rotate ? ");
		        readf(" %d", &liRot);
		        if(liRot<1)
		        	write("Input a positive number\n");
        	}while(liRot<1);//Keep asking if a negatice number


			liRot%=liEle;// Reduce rotations for minimal executino

		for(liCount=liEle-1, liAcc=liRot-1; liAcc>=0; liCount--, liAcc--)	{//Revrse loop for rotation
			liaFinal[liAcc]=liaOrig[liCount];
		}
		for(liCount=0; liRot<liEle; liCount++, liRot++) {//Complementary loop for missed elements
			liaFinal[liRot]=liaOrig[liCount];
		}
		write("The original patter is : ");//Output the original sequence
		for(liCount=0; liCount<liEle; liCount++)	{
			write(liaOrig[liCount], " ");
		}
		write("\n");//New line for next loop output
		write("The final is : ");//Final sequence output
		for(liCount=0; liCount<liEle; liCount++)	{//loop for Final sequence output
			write(liaFinal[liCount], " ");
		}
		write("\nDo you want to rotate again ? y/n ");//Option to rotate again
		readf(" %c", &lcRot);
		if(lcRot == 'y' || lcRot == 'Y')	{
			for(liCount=0; liCount<liEle; liCount++)//Keep the Final sequence
				liaOrig[liCount]=liaFinal[liCount];
		}
		else	{
			write("Do you want to make an adicional  sequence ? a/A ");//Option to make a new sequence
			readf(" %c", &lcRot);
		}
	        }while(lcRot == 'y' || lcRot == 'Y');
}while(lcRot == 'A' || lcRot == 'a');//Loop for restarting the program
write("End of program\n");//Nothing else to do
}

August 08, 2015
Here's what happens :

How many elements need to be used? 5
Input the element : 1 1
Input the element : 1 2
Input the element : 1 3
Input the element : 1 4
Input the element : 1 5
How many positions do you wish to rotate ? 3
The original patter is : 5 0 0 0 0
The final is : 0 0 0 5 0
Do you want to rotate again ? y/n y
How many positions do you wish to rotate ? 2
The original patter is : 0 0 0 5 0
The final is : 5 0 0 0 0
Do you want to rotate again ? y/n n
Do you want to make an adicional  sequence ? a/A a
How many elements need to be used? 4
Input the element : 1 1
Input the element : 1 2
Input the element : 1 3
core.exception.RangeError@gen014.d(31): Range violation
----------------
0x4077ef _Dmain
	???:0
0x41684e void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().void __lambda1()
	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
0x416d18 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()
	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
0x416c45 _d_run_main
	../../../../src/libphobos/libdruntime/rt/dmain2.d:416
0x7f8c84eeda3f __libc_start_main
	???:0
0x406058 _start
	???:0
0xffffffffffffffff ???
	???:0

August 08, 2015
On Saturday, 8 August 2015 at 15:57:15 UTC, Binarydepth wrote:
> Here's what happens :
>
> How many elements need to be used? 5
> Input the element : 1 1
> Input the element : 1 2
> Input the element : 1 3
> Input the element : 1 4
> Input the element : 1 5
> How many positions do you wish to rotate ? 3
> The original patter is : 5 0 0 0 0
> The final is : 0 0 0 5 0
> Do you want to rotate again ? y/n y
> How many positions do you wish to rotate ? 2
> The original patter is : 0 0 0 5 0
> The final is : 5 0 0 0 0
> Do you want to rotate again ? y/n n
> Do you want to make an adicional  sequence ? a/A a
> How many elements need to be used? 4
> Input the element : 1 1
> Input the element : 1 2
> Input the element : 1 3
> core.exception.RangeError@gen014.d(31): Range violation
> ----------------
> 0x4077ef _Dmain
> 	???:0
> 0x41684e void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll().void __lambda1()
> 	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
> 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
> 	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
> 0x416d18 void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).runAll()
> 	../../../../src/libphobos/libdruntime/rt/dmain2.d:408
> 0x416abe void rt.dmain2._d_run_main(int, char**, extern (C) int function(char[][])*).tryExec(scope void delegate())
> 	../../../../src/libphobos/libdruntime/rt/dmain2.d:383
> 0x416c45 _d_run_main
> 	../../../../src/libphobos/libdruntime/rt/dmain2.d:416
> 0x7f8c84eeda3f __libc_start_main
> 	???:0
> 0x406058 _start
> 	???:0
> 0xffffffffffffffff ???
> 	???:0

This is happening because 'num' is reading the value of each element in the array; it's not a count. Once it reads the 5 in element, it attempts to put the next number into element 5, which of course doesn't exist.

This is also why the first time through there is only one value in the array that isn't 0: 'num' the first time through is always zero because the values of the dynamic array are .init-ed to zero.

You can fix it like the following:

foreach(num, element; liaOrig)	{//Data input loop
		
			writefln("num: %s current element: %s liaOrig.length: %s", num, element, liaOrig.length);

			write("Input the element : ", num+1, " ");
			readf(" %d", &liaOrig[num]);
		}

Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is  stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime.

As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array.

Hope this helps!
August 08, 2015
On Saturday, 8 August 2015 at 17:19:08 UTC, DarthCthulhu wrote:
> You can fix it like the following:
>
> foreach(num, element; liaOrig)	{//Data input loop
> 		
> 			writefln("num: %s current element: %s liaOrig.length: %s", num, element, liaOrig.length);
>
> 			write("Input the element : ", num+1, " ");
> 			readf(" %d", &liaOrig[num]);
> 		}
>
> Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is  stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime.
>
> As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array.
>
> Hope this helps!

Thanks that fixed it. I just realized that I'm doing it wrong. This is the new code :

	foreach(num; 0..liEle)	{//Data input loop

		write("Input the element : ", num+1, " ");
		readf(" %d", &liaOrig[num]);
	}
August 08, 2015
On Saturday, 8 August 2015 at 18:24:48 UTC, Binarydepth wrote:
> On Saturday, 8 August 2015 at 17:19:08 UTC, DarthCthulhu wrote:

>> Now 'num' is just an iterative number starting from 0 (the .init value of an int), while the actual element value is  stored in 'element'. I added the writefln() statement to make it a bit more clear during runtime.
>>
>> As an addenum, you don't need the liaOrig[0 .. $] in the foreach statement; just the name of the array variable is required to walk the entire array.
>>
>> Hope this helps!
>
> Thanks that fixed it. I just realized that I'm doing it wrong. This is the new code :
>
> 	foreach(num; 0..liEle)	{//Data input loop
>
> 		write("Input the element : ", num+1, " ");
> 		readf(" %d", &liaOrig[num]);
> 	}

Even better :

foreach(num; 0..liaOrig.length
August 09, 2015
On Saturday, 8 August 2015 at 18:28:25 UTC, Binarydepth wrote:
>> This is the new code :
>>
>> 	foreach(num; 0..liEle)	{//Data input loop
>>
>> 		write("Input the element : ", num+1, " ");
>> 		readf(" %d", &liaOrig[num]);
>> 	}
>
> Even better :
>
> foreach(num; 0..liaOrig.length

I believe they usually do something like:

foreach( num, ref elem; liaOrig){

}

which creates the index num and the reference to the element of range liaOrig.

It also seems that a lot of discussion is going on about reducing use of foreach loops in their preferred style, so you might want to try some of that.


August 09, 2015
On Sunday, 9 August 2015 at 00:22:53 UTC, Jay Norwood wrote:
> On Saturday, 8 August 2015 at 18:28:25 UTC, Binarydepth wrote:
>>> This is the new code :
>>>
>>> 	foreach(num; 0..liEle)	{//Data input loop
>>>
>>> 		write("Input the element : ", num+1, " ");
>>> 		readf(" %d", &liaOrig[num]);
>>> 	}
>>
>> Even better :
>>
>> foreach(num; 0..liaOrig.length
>
> I believe they usually do something like:
>
> foreach( num, ref elem; liaOrig){
>
> }
>
> which creates the index num and the reference to the element of range liaOrig.
>
> It also seems that a lot of discussion is going on about reducing use of foreach loops in their preferred style, so you might want to try some of that.

So I should use the REF like this ?

import std.stdio : writeln;
void main()     {
        immutable a=5;
        int[a] Arr;
        foreach(num; 0..a)      {
                Arr[num] = num;
        }
        foreach(num, ref ele; Arr)      {
                writeln(Arr[ele]+1);//Using the REF
        }
}
August 09, 2015
On Sunday, 9 August 2015 at 15:37:23 UTC, Binarydepth wrote:
>
> So I should use the REF like this ?
>
> import std.stdio : writeln;
> void main()     {
>         immutable a=5;
>         int[a] Arr;
>         foreach(num; 0..a)      {
>                 Arr[num] = num;
>         }
>         foreach(num, ref ele; Arr)      {
>                 writeln(Arr[ele]+1);//Using the REF
>         }
> }

No. `ele` is the array element; reindexing the array with it is incorrect. `ref` just means that you can assign back to the array (like `ele = 123; assert(Arr[num] == 123);`); it's unnecessary here though.

August 09, 2015
On Sunday, 9 August 2015 at 15:37:23 UTC, Binarydepth wrote:
> So I should use the REF like this ?
>
> import std.stdio : writeln;
> void main()     {
>         immutable a=5;
>         int[a] Arr;
>         foreach(num; 0..a)      {
>                 Arr[num] = num;
>         }
>         foreach(num, ref ele; Arr)      {
>                 writeln(Arr[ele]+1);//Using the REF
>         }
> }

The reference v is to the array member in this case, rather than making a copy.  In the last loop c is a copy.  No big deal for this case of int Arr members, but if Arr was made up of struct members, you might not want to be making copies.

The i+3 initialization is just so you can see that v is the Arr member (not the index) in the other loops.

import std.stdio : writeln;
void main()     {
	immutable a=5;
	int[a] Arr;
	foreach(i, ref v; Arr)      {
		v = i+3;
	}
	foreach( ref v; Arr)      {
		writeln(v);
	}
	foreach( c; Arr)      {
		writeln(c);
	}
}

August 09, 2015
On Sunday, 9 August 2015 at 16:42:16 UTC, Jay Norwood wrote:
> The i+3 initialization is just so you can see that v is the Arr member (not the index) in the other loops.
>
> import std.stdio : writeln;
> void main()     {
> 	immutable a=5;
> 	int[a] Arr;
> 	foreach(i, ref v; Arr)      {
> 		v = i+3;
> 	}
> 	foreach( ref v; Arr)      {
> 		writeln(v);
> 	}
> 	foreach( c; Arr)      {
> 		writeln(c);
> 	}
> }

Oooh... I like how this works

import std.stdio : writeln, readf;
void main()     {
        immutable a=5;
        int[a] Arr;
        int nim;
        foreach(num, ref nem; Arr)      {
                readf(" %s", &nem);
        }
        foreach(num; Arr)      {
                writeln(num);
        }
}
« First   ‹ Prev
1 2