Addressing your last point about "how do I need to change my mentality, to correctly program in q?":
You need to utilise over (/), scan (\) and .z.s rather than using loops.
For example, your problem could be solved in the following ways:
(note that these would not actually be the best solutions for your particular problem - indexing is the better approach there - but nonetheless these solutions below should help get the point across)
price:18.54 18.53 18.53 18.52 18.57 18.9 18.9 18.77 18.59 18.51 18.37
q)3#'{1_x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
i.e iterate over the list, chop one off each time, take first 3 of each iteration
or similarly
q)3#'{1 rotate x}\[8;price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
i.e. rotate by 1 eight times, take first 3 of each rotation
Using a .z.s approach
q){$[2<count x;enlist[3#x],.z.s 1_x;()]}[price]
18.54 18.53 18.53
18.53 18.53 18.52
18.53 18.52 18.57
18.52 18.57 18.9
18.57 18.9 18.9
18.9 18.9 18.77
18.9 18.77 18.59
18.77 18.59 18.51
18.59 18.51 18.37
i.e. if there are at least 3 elements left, take first 3, then chop off first item and re-apply same function to the shortened list.
Using over (/) would be convoluted in this example but in general over is usful for replacing "while" type constructs
i:0
a:0;
while[i<10;i+:1;a+:10]
is better achieved using
q){x+10}/[10;0]
100
i.e. add 10, ten times with a starting (seed) value of zero.
b:();
while[not 18~last b;b,:1?20]
i.e keep appending random numbers between 1 and 20 until you hit 18, then stop.
is better achieved using
q){x,1?20}/[{not 18~last x};()]
1 2 16 5 8 18
i.e append a random number between 1 and 20, iterate so long as the check function returns true, starting off with () as seed value
There are many other options for using scan and over, depending on whether the function you're iterating over is monadic/diadic etc.
As a broad generalisation:
a "for i=1:10" type loop can be achieved in q using "function each i",
a "do" type loop can be achieved in q using "function/[numOfTimes;seed]",
a "while" type loop can be achieved in q using "function/[booleanCheckFunction;seed]"
while
anddo
keywords. – Marceline