My question seams to be quite easy but currently I am not seeing the wood for the trees.
I've written code in swift 2 using a for-loop with two counter like:
for var i = 0, j = 1; i < 5; i++, j++ {
code...
}
but, with swift 3 this become deprecated.
I mean with one variable it's clear:
for i in 0 ..< endcondition {
code...
}
but how would the code with a for-loop looks like in swift 3 with two counter, without interlacing two for-loop?
Thanks in advance
Stefan
In this particular case
for i in 0..<5 {
let j = i + 1
print(i, j)
}
var i:Int = 0
var j:Int = 1
for each in 0...arrayCount -1{
//do stuff
/// place increments in closures as needed
j += 1
i += 1
}
You may want to consider on while loop to allow usage of evaluating multiple values to signal a stop.
while condition {
statements
Change condition
}
Related
How can I do this java code in kotlin using just one for loop?
for(int i=0, j=0; i < 6 && j < 6; i++, j+=2) {
// code here
}
There is no way to iterate over multiple variables. In this case, the easiest thing you can do is:
for (i in 0..3) {
val j = i * 2
}
In a more general case, you can rewrite this as a while loop:
var i = 0
var j = 0
while (i < 6 && j < 6) {
// code here
i++
j += 2
}
I really appreciate gidds's answer
but there is another easier way to write for in loops for two variables
for ( (i, j) in (0..6).zip(0..6 step 2)){
println("values are: $i, $j")
}
Above code run just fine as expected
you can also write for in loops easily for three variable. See the following code.
In this code I tried to implement a three variable series
// 1.2.3 + 2.3.4 + 3.4.5 + ... + n(n+1)(n+2)
fun main(args: Array<String>) {
// taking int input from console
val number: Int = readLine()!!.toInt()
var sum: Int = 0
// here second variable jPair becomes pair because of second nested zip
for ( (i, jPair) in (1..number).zip((0..number + 1).zip(2..number + 2))) {
println("values are: $i, ${jPair.first}, ${jPair.second}")
sum += (i * jPair.first * jPair.second)
}
println("Series sum is: $sum")
}
Now, let's implement four variable for in loop
In the following code I am trying to implement a four variable series
// 1.3.5.7 + 3.5.7.9 + 5.7.9.11 + ... + n(n+2)(n+4)(n+6)
fun main(args: Array<String>) {
// taking int input from console
val number: Int = readLine()!!.toInt()
var sum: Int = 0
// here second variable iPair becomes pair because of first nested zip
// here second variable jPair becomes pair because of second nested zip
for ( (iPair, jPair) in ((1..number step 2).zip(3..number + 2 step 2)).zip((5..number + 4 step 2).zip(7..number + 6 step 2))) {
println("values are: ${iPair.first}, ${iPair.second}, ${jPair.first}, ${jPair.second}")
sum += (iPair.first * iPair.second * jPair.first * jPair.second)
}
println("Series sum is: $sum")
}
This way we can implement multiple variable for in loops easily.
yole's answer is almost certainly the simplest and most efficient approach.
But one alternative you might look at is zipping sequences together, e.g.:
for ((i, j) in sequence{ yieldAll(0 until 6) }.zip(sequence{ yieldAll(0 until 6 step 2) })) {
// code here
}
That's much more readable with a utility function, e.g.:
fun <T, U> seqs(it1: Iterable<T>, it2: Iterable<U>)
= sequence{ yieldAll(it1) }.zip(sequence{ yieldAll(it2) })
for ((i, j) in seqs(0 until 6, 0 until 6 step 2)) {
// code here
}
That's less efficient (initially creating Iterables, Ranges, and Sequences, and then a Pair for each iteration). But it's the exact equivalent of the code in the question. And because it defines each range in one place, it does at least make them very clear.
(I think this needs Kotlin 1.3. There are probably simpler and/or more general ways of doing it; feel free to edit this if you can improve it!)
I have a problem:
For example, there are N number of generations, and I want to execute these generations in jstree like parents and children.
I can only use a fixed number of nested for loops. I don't know how to make it dynamic, i.e., I want to nest N for loops.
How can I do this?
I can only use a fixed number of nested loops, such as
for (i=0;i<=list1.size;i++){
for (j=0;j<=list2.size;j++){
// and some other loops
}
}
but this is static. I want to be able to dynamically execute N number of loops.
As you said, you can't have an arbitrary number of nested for-loops. The way to achieve this is by using recursion.
Here's an example:
function foo(list_of_lists) {
// base case
if (list_of_lists.length == 0) return;
// otherwise, we'll get the head of the list, and continue
list = list_of_lists[0];
for (var idx = 0; idx <= list.length; idx++) {
// do something
// now recursively nest the next list in a for-loop
foo(list_of_lists.splice(1));
}
}
For N lists, this will build up nested for-loops that look like:
for (var idx = 0; idx <= list0.length; idx++) {
for (var idx2 = 0; idx2 <= list2.length; idx2++) {
for (var idx3 = 0; idx3 <= list3.length; idx3++) {
...
}
}
}
If you need a jstree specific solution - set core.data to a function - it will be executed each time a node needs to be loaded - that way you can have an "infinite" dynamic tree so to speak.
for (i = 0; i < 10; i++) {
doStuff();
}
That's the JavaScript code that I Want to convert to CoffeeScript.
doStuff() for i in [0 .. 9]
This is explained on the introduction page: http://coffeescript.org/#loops
Edit/Update by JP:
The exact translation is:
doStuff() for i in [0...10]
You need to be careful with the ".." vs "...", for example:
count = 0
doStuff() for i in [0..count] #still executes once!
So you think, no problem... I'll just loop until count-1!
count = 0
doStuff() for i in [0..count-1] #executes twice!! '0' and then '-1'
Literal translation of:
for (var i = 0; i < someCount; ++i)
doStuff()
is
for i in [0...someCount]
doStuff()
The marked answer is functionaly correct but the generated code doesn't match the original javascript.
The right way (read, the one closest to the following javascript)
for (i = 0; i < 10; i++) {
doStuff();
}
is doStuff() for i in [0..someCount] by 1
Note the by 1 on the for loop.
Now this code, still creates an extra _i variable. If you can't live with it, then use the following:
i=0
while i<=someCount
doStuff()
i++
Previous answers work. However, dropping the i generates it better for me:
for [0...10]
doStuff()
or
doStuff() for [0...10]
The other solutions add an extra iterator variable i for you to use inside of the loop, for example doStuff(i), but from http://coffeescript.org/v1/#loops:
If you don’t need the current iteration value you may omit it:
browser.closeCurrentTab() for [0...count]
In detail, the translation of for i in [0...10] is for (i = j = 0; j < 10; i = ++j), whereas the translation of for [0...10] is for (i = 0; i < 10; i++).
Note the discussion in other comments about 2-dots versus 3-dots ([0..9] vs. [0...10]).
How should i set a while loop counter? When is it supposed to be 1 and when is it supposed to be 0?
In general, how should I start with a while loop problem?
It depends on what you are doing and what you want to accomplish.
If you are iterating through an array, then you will probably want to start your counter with 0, since arrays are 0-indexed (the first element of the array is at position 0). For example:
int integerArray[] = {1, 2, 3}
int counter = 0;
while ( counter < 3 )
{
System.out.println(integerArray[counter]);
++counter;
}
If you are not iterating through an array, it does not really matter what you start your counter with, but it probably does matter how many times you want the loop to iterate. If you want it to iterate 100 times, you could either start with 0 and increment the counter by 1 until counter < 100, or you could start the counter at 1 and increment it by 1 until counter <= 100. It's totally up to you. For example:
int counter = 0;
while ( counter < 100 )
{
//prints the numbers 0-99
System.out.println(counter);
++counter;
}
int counter = 1;
while ( counter < 101 )
{
//prints the numbers 1-100
System.out.println(counter);
++counter;
}
Actually, for both of these cases, for loops would probably serve you better, but the same concept applies:
for (int i = 0; i < 100; ++i)
{
//prints the numbers 0-99
System.out.println(i);
}
A while loop, depending on the language, typically works off a boolean value, not a counter.
while (condition)
{
// Do something until condition == false
}
For "counter" style looping, you'll typically want (again, in most languages) a for loop instead.
Which one is faster? Why?
var messages:Array = [.....]
// 1 - for
var len:int = messages.length;
for (var i:int = 0; i < len; i++) {
var o:Object = messages[i];
// ...
}
// 2 - foreach
for each (var o:Object in messages) {
// ...
}
From where I'm sitting, regular for loops are moderately faster than for each loops in the minimal case. Also, as with AS2 days, decrementing your way through a for loop generally provides a very minor improvement.
But really, any slight difference here will be dwarfed by the requirements of what you actually do inside the loop. You can find operations that will work faster or slower in either case. The real answer is that neither kind of loop can be meaningfully said to be faster than the other - you must profile your code as it appears in your application.
Sample code:
var size:Number = 10000000;
var arr:Array = [];
for (var i:int=0; i<size; i++) { arr[i] = i; }
var time:Number, o:Object;
// for()
time = getTimer();
for (i=0; i<size; i++) { arr[i]; }
trace("for test: "+(getTimer()-time)+"ms");
// for() reversed
time = getTimer();
for (i=size-1; i>=0; i--) { arr[i]; }
trace("for reversed test: "+(getTimer()-time)+"ms");
// for..in
time = getTimer();
for each(o in arr) { o; }
trace("for each test: "+(getTimer()-time)+"ms");
Results:
for test: 124ms
for reversed test: 110ms
for each test: 261ms
Edit: To improve the comparison, I changed the inner loops so they do nothing but access the collection value.
Edit 2: Answers to oshyshko's comment:
The compiler could skip the accesses in my internal loops, but it doesn't. The loops would exit two or three times faster if it was.
The results change in the sample code you posted because in that version, the for loop now has an implicit type conversion. I left assignments out of my loops to avoid that.
Of course one could argue that it's okay to have an extra cast in the for loop because "real code" would need it anyway, but to me that's just another way of saying "there's no general answer; which loop is faster depends on what you do inside your loop". Which is the answer I'm giving you. ;)
When iterating over an array, for each loops are way faster in my tests.
var len:int = 1000000;
var i:int = 0;
var arr:Array = [];
while(i < len) {
arr[i] = i;
i++;
}
function forEachLoop():void {
var t:Number = getTimer();
var sum:Number = 0;
for each(var num:Number in arr) {
sum += num;
}
trace("forEachLoop :", (getTimer() - t));
}
function whileLoop():void {
var t:Number = getTimer();
var sum:Number = 0;
var i:int = 0;
while(i < len) {
sum += arr[i] as Number;
i++;
}
trace("whileLoop :", (getTimer() - t));
}
forEachLoop();
whileLoop();
This gives:
forEachLoop : 87
whileLoop : 967
Here, probably most of while loop time is spent casting the array item to a Number. However, I consider it a fair comparison, since that's what you get in the for each loop.
My guess is that this difference has to do with the fact that, as mentioned, the as operator is relatively expensive and array access is also relatively slow. With a for each loop, both operations are handled natively, I think, as opossed to performed in Actionscript.
Note, however, that if type conversion actually takes place, the for each version is much slower and the while version if noticeably faster (though, still, for each beats while):
To test, change array initialization to this:
while(i < len) {
arr[i] = i + "";
i++;
}
And now the results are:
forEachLoop : 328
whileLoop : 366
forEachLoop : 324
whileLoop : 369
I've had this discussion with a few collegues before, and we have all found different results for different scenarios. However, there was one test that I found quite eloquent for comparison's sake:
var array:Array=new Array();
for (var k:uint=0; k<1000000; k++) {
array.push(Math.random());
}
stage.addEventListener("mouseDown",foreachloop);
stage.addEventListener("mouseUp",forloop);
/////// Array /////
/* 49ms */
function foreachloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var i:uint=0;
for each (var n:Number in array) {
i++;
tmp+=n;
}
trace("foreach", i, tmp, getTimer() - t1);
}
/***** 81ms ****/
function forloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var l:uint=array.length;
for(var i:uint = 0; i < l; i++)
tmp += Number(array[i]);
trace("for", i, tmp, getTimer() - t1);
}
What I like about this tests is that you have a reference for both the key and value in each iteration of both loops (removing the key counter in the "for-each" loop is not that relevant). Also, it operates with Number, which is probably the most common loop that you will want to optimize that much. And most importantly, the winner is the "for-each", which is my favorite loop :P
Notes:
-Referencing the array in a local variable within the function of the "for-each" loop is irrelevant, but in the "for" loop you do get a speed bump (75ms instead of 105ms):
function forloop(e) {
var t1:uint=getTimer();
var tmp:Number=0;
var a:Array=array;
var l:uint=a.length;
for(var i:uint = 0; i < l; i++)
tmp += Number(a[i]);
trace("for", i, tmp, getTimer() - t1);
}
-If you run the same tests with the Vector class, the results are a bit confusing :S
for would be faster for arrays...but depending on the situation it can be foreach that is best...see this .net benchmark test.
Personally, I'd use either until I got to the point where it became necessary for me to optimize the code. Premature optimization is wasteful :-)
Maybe in a array where all element are there and start at zero (0 to X) it would be faster to use a for loop. In all other case (sparse array) it can be a LOT faster to use for each.
The reason is the usage of two data structure in the array: Hast table an Debse Array.
Please read my Array analysis using Tamarin source:
http://jpauclair.wordpress.com/2009/12/02/tamarin-part-i-as3-array/
The for loop will check at undefined index where the for each will skip those one jumping to next element in the HastTable
guys!
Especially Juan Pablo Califano.
I've checked your test. The main difference in obtain array item.
If you will put var len : int = 40000;, you will see that 'while' cycle is faster.
But it loses with big counts of array, instead for..each.
Just an add-on:
a for each...in loop doesn't assure You, that the elements in the array/vector gets enumerated in the ORDER THEY ARE STORED in them. (except XMLs)
This IS a vital difference, IMO.
"...Therefore, you should not write code that depends on a for-
each-in or for-in loop’s enumeration order unless you are processing
XML data..." C.Moock
(i hope not to break law stating this one phrase...)
Happy benchmarking.
sorry to prove you guys wrong, but for each is faster. even a lot. except, if you don't want to access the array values, but a) this does not make sense and b) this is not the case here.
as a result of this, i made a detailed post on my super new blog ... :D
greetz
back2dos