I am trying to go through the array (fixed 10 items array in this case) and would like to return the INDEX to where I would like to store a value of the first occurence where the value is NULL. How would you do this in Motoko ?
Currently, I am trying to do this using the Iter library but the compiler does not like this
private let canisters : [var ?CanisterState<Bucket, Nat>] = Array.init(0, null);
let canistersIter = Iter.range(0, canisters.size() - 1);
let index = for(i in canistersIter) {
switch (canisters[i]) {
case null {
break i;
};
case (?canister) continue // what should I return as value after continue as it fails if there is none?;
};
};
The docs are pretty confusing to me regarding this, can’t figure out how to do this. Any help appreciated 
I have “solved” this issue by using following code:
var index: Nat = 0;
let canistersIter = Iter.range(0, canisters.size() - 1);
for (canisterState in canistersIter) {
switch(canisters[canisterState]) {
case null { index := canisterState };
case (?cs) {};
}
};
I am not sure if this is the (best) way of doing it or not, would like opinion of more experienced ICP devs on this whether or not it’s a good way to do so and/or if there is an easier way (maybe Iter does not need to be used at all)?
I think your solution is okayish, except for two remarks:
- It will not be able to distinguish finding
null
at the first slot from not having found it anywhere. I think you actually want type ?Nat
.
- You can simplify the iterator by using
canister.keys()
.
Together, that would be:
var index : ?Nat = null;
for (i in canisters.keys()) {
switch(canisters[i]) {
case null { index := ?i };
case (?cs) {};
}
};
Alternatively, if you’re keen on avoiding the mutable variable, you could do something like this, which is closer to your first attempt:
let index : ?Nat =
label l {
for (i in canisters.keys()) {
switch(canisters[i]) {
case null { break l(?i) };
case (?cs) {};
}
};
null
}
};
But I’m not sure that’s more readable.
3 Likes
Thank you very much for the examples!
I think that I will probably switch to using the label example since in my code i just want to find the first element in the array where value is null (so basically first element that was not yet set) and I believe the break l(?i)
is the way to do it, without the need to iterate over the whole array (will be faster)
Very cool, I didn’t know that labeled expressions were a thing until reading this.
2 Likes
You could also wrap the switch as a local function and then even use something like map instead of imperatively iterating.