Do something every nth iteration of loop in Objective-c or Swift - objective-c

Within a loop, it is possible to do something every other time by using odd and even and testing for even. I would like to do something a fixed number of times eg four no matter how many iterations there are in the loop (value of i). Is there a way to do something every nth time?
I think there must be a way by incrementing a second counter, but having trouble getting it.
A Loop
int i = 0;
int movinglimit = 0;
int incr = [myItems count]/4;;// there might be 10, 20 or 30 items. I only want to do something four times
while (i < [myItems count]) {
if ((i % 2) == 0) {
//do something if even
}
if (i>movinglimit) {
//do something a total of four times
}
if (i==moving limit+1) {
movinglimit = movinglimit + incr;
}
i++;
}

Assuming myItems is an NSArray or NSMutableArray or NSSet you can apply methods on all objects at once which is smarter than implementing an iteration looping thru object by object yourself. That way you take full advantage of objC.
[myItems makeObjectsPerformSelector:#selector(yourObjectMethodToApply)];
This has the side effect that nothing is done/applied if myItems is nil
A short comment on your pseudocode.
Be careful with while loops without any increment inside.
The one you show here is only looping once.
//iteration backward
NSUInteger i = myItems.count-1;
for ( ; i>0; ) {
if ((i % 2) == 0) {
// do stuff if 4th is even
}
// do stuff on every 4th one
i-=4; //increment does not have to be in for () declaration
}
identify the similarity (also backward iteration) to
NSUInteger i = myItems.count-1;
while (i>0) {
// do stuff on each 4th item
//check for odd/even
myItems[i] = i % 2 ? /* even stuff */ : /* odd stuff */;
i-=4; //decrement i
}

You tagged Swift so I assume you want Ob-C or Swift answers. You can enumerate the loop and use that enumeration (which I call n below). The first enumeration will always be 0, of course, so to simplify the even/odd parity, just add 1 to make the first iteration 1.
let data = ["a", "b", "c", "d", "e", "f", "g", "h", "i", "j"]
for (n, i) in data.enumerated() {
if (n+1).isMultiple(of: 2) {
print(n+1, i) // every even iteration
}
}
// output: 2 b, 4 d, 6 f, 8 h, 10 j
for (n, i) in data.enumerated() {
if (n+1) <= (4*2), (n+1).isMultiple(of: 2) {
print(n+1, i) // every even iteration but only 4 times
}
}
// output: 2 b, 4 d, 6 f, 8 h

Related

for loop with two indices in Kotlin

It's possible to use for loop with double indices in Java, e.g:
for (int j = 0, k = myArray.length - 1; j < myArray.length; j++, k--)
To iterate myArray elements from the first element using j and from the last element using k simultaneously without using inner loop. How can we do this in Kotlin without using inner loop.
Kotlin doesn't provide a way to permit what you attempt to do.
Because I imagine your case is purely for exemple, I purpose you two solutions:
1. The good old way
The most optimized for the exemple you give.
for (i in a.indices) {
val j = a.size - 1 - i
println("($i, $j)")
}
(0, 3)(1, 2)(2, 1)(3, 0)
See code snippet on play.kotlinlang.org
2. The .zip() way
Can be usefull on some contexts, the zip method combine two lists of the same size on one list of Tuples which can be used after directly.
val indices = a.indices;
for (i in indices.zip(indices.reversed())) {
println(i)
}
(0, 3)(1, 2)(2, 1)(3, 0)
See code snippet on play.kotlinlang.org
You don't need an inner loop. Just create an additional variable inside for loop.
for(j in myArray.indices) {
val k = myArray.size - 1 - j
// Use j and k here
}
Or alternatively,
var k = myArray.size - 1
for(j in myArray.indices) {
// Use j and k here
k--
}
generateSequence() is powerful alternative for complex loops. Not so fast as pure for/while loop but very flexible and easy.
generateSequence(
0 to myArray.size - 1 // initial values
) {
it.first + 1 to it.second - 1 // new values after each iteration
}.takeWhile {
it.first < myArray.size // limit
}.forEach { (j, k) ->
println("$j $k")
}
And yes, it's good idea to not iterate second variable but calculate it from first (if applicable), as suggested in other answers.

Kotlin - Loop Zero Times

Since there is no traditional loop in Kotlin (as per this article), how would you write a for loop in Kotlin that loops n times, or specifically, zero times if n is zero?
The equivalent in Java would be
int n = 0;
for (int index = 0; index < n; index++) {
// do this n times...
}
You could use repeat for this instead of a for loop or a range...
val n = 5
repeat(n) {
// ...
}
If you need to use the counter, you can either refer to it with the default it or rename it:
repeat(n) { i ->
// Do something with i
}
Use ranges and progressions
val n = 5
for (a in 0 until n) {
//Do something
}

Least Common Multiple with while loop, Javascript

I'm trying to find the least common multiple of an array of integers, e.g. if there are 2 numbers given (7, 3) then my task is to find the LCM of the numbers 3 through 7 (3,4,5,6,7 in that case).
My solution would be to add the maximum number to a new variable (var common) until the remainders of all of the numbers in the array (common % numBetween[i]) equal 0. There are more efficient ways of doing this, for example applying the Euclidean Algorithm, but I wanted to solve this my way.
The code:
function smallestCommons(arr) {
var numBetween = [];
var max = Math.max.apply(Math, arr);
var min = Math.min.apply(Math, arr);
while (max - min !== -1) {
numBetween.push(min);
min += 1;
} //this loop creates the array of integers, 1 through 13 in this case
var common = max;
var modulus = [1]; //I start with 1, so that the first loop could begin
var modSum = modulus.reduce(function (a, b) {
return a + b;
}, 0);
while (modSum !== 0) {
modulus = [];
for (var i = 0; i < numBetween.length; i++) {
modulus.push(common % numBetween[i]);
}
if (modSum !== 0) {
common += max;
break; //without this, the loop is infinite
}
}
return common;
}
smallestCommons([1,13]);
Now, the loop is either infinite (without break in the if statement) so I guess the modSum never equals 0, because the modulus variable always contains integers other than 0. I wanted to solve this by "resetting" the modulus to an empty array right after the loop starts, with
modulus = [];
and if I include the break, the loop stops after 1 iteration (common = 26). I can't quite grasp why my code isn't working. All comments are appreciated.
Thanks in advance!
I may be false, but do you actually never change modSum within the while-loop? If so, this is your problem. You wanted to do this by using the function .reduce(), but this does not bind the given function, so you have to call the function each time again in the loop.

Looping over an NSmutatable Array starting from a certain index

I have a quick question how can I loop over an NSMutable array starting from a certain index.
For Example I have these double loops I want k to start from the same index as l.
for (Line *l in L)
{
for (Line *k in L)
{
............
}
}
To elaborate further, lets say L has 10 object so l start from 0-10 and k from 0 -10. What I want is if l is equal 1 k should start from 1-10 rather than 0 - 10 and when l is equal 2 k should start from 2- 10 rather than 0. Any help is Appreciated
Objective-C is an extension of C, lookup the C for loop and you'll have your answer. HTH
Addendum
I was going to let you benefit from the learning experience of looking up the C for yourself, however at the time of writing all other answers since added give the code but it is not complete, so here is what you need to produce the l and k values in the order you wish:
for(NSInteger lIndex = 0; lIndex < L.count; lIndex++)
{
Line *l = L[lIndex]; // index into your array to get the element
for(NSInteger kIndex = lIndex; kIndex < L.count; kIndex++)
{
Line *k = L[kIndex];
// process your l and k
}
}
As you can see the for has three sub-parts which are the initialisation, condition, and increment. The initialisation is performed first, then the condition to determine whether to execute the for body, and the increment is executed after the statements in the body and before the condition is tested to determine if another iteration should be performed. A for loop is roughly (there are some differences that are unimportant here) to the while loop:
initialisation;
while(condition)
{
body statements;
increment;
}
You simply need to modify for-statement.
NSInteger indexYouNeed;
NSInteger iterationCount;
for (int i = indexYouNeed; i < iterationCount; i++) {
/* Your code here */
}
You may find this link helpfulll.
You have to use an indexed (ordinary) for loop instead of fast enumeration (for-in):
int l;
for (l=startValue; l<=endValue; l++)
{
int i;
for (int i=l; i<=endValue; i++)
{
…
}
}

Objective C reference to a variable

I have a list of variables that are named based on two digits then a word i.e. val11 or val26
I need to perform a check on whether a certain value for a variable is equal to the next variable i.e. that val32 == val33
I have the names of the first variables that I need to check in an NSArray (i.e val33)
I can then write a function to perform the check as a lot of long winded if statements
-(void)checkValues:(NSArray *)valueArray {
for (int x = 0; x < [valueArray count]; x++) {
tempStr = [offFiles objectAtIndex:x];
//split variable name
NSString *value = [tempStr substringWithRange:NSMakeRange(3,2];
int numValue= [value intValue];
//long winded if statement
if (numValue == 11) {
if(val11 == val12) {
//do something
}
}
if (numValue == 12) {
if(val12 == val13) {
//do something
}
}
.... etc
if (numValue == 87) {
if(val87 == val88) {
//do something
}
}
}
}
Is there any way I can remove the long winded if statement and replace it with a reference to the next variable so that no matter what variable name is in the array I can easily just check it against the next variable
Something like the excel command indirect
=INDIRECT(CONCATENATE("Cell!A",numValue + 1))
Unless there is some need for you to store your data in a set of discrete separate variables, this is clearly a situation were an array would work for you. This could be either a c-style array or one using NSArray - its up to you.
Using a c-style array (assuming 10 completely made up values):
int myValues[10] = { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 }
Then your series of if statements can be reduced to one:
if (myValues[numValue] == myValues[numValue+1]) {
// so something
}
So if numValue is 3, it would compare myValues[3] and myValues[4] - essentially the same as comparing val3 and val4 in your scheme. Please note that arrays are zero based - the first value is accessed myValue[0] - so if your numbering scheme is 1-based then you need to subtract 1, e.g.:
if (myValues[numValue-1] == myValues[numValue]) {
// do something
}
Beside from the syntax bugs (like starting variable names with a number), what you are looking for is the switch() statement:
switch(a)
{
case 1: // if a is 1 do the following
printf("a is 1");
break;
case 2: // if a is 2
printf("a is 2");
break;
....
default: // if a was none of the cases before do this
printf("a sucks!!");
}
Notice that you always need a break; statement at the end of each case x: