For example in C you would be able to write
for (int i = 0; i < 10 ; i++) {
if (i == 2) i += 1
// do stuff
}
Since Scala uses ranges, how would we modify the iterator?
You can use a guard:
for (i <- 0 to 10; if i != 2) println(i)
This would print the numbers from 0 to 10, excluding 2.
You can see this code in action an play around with it here on Scastie.
You would have multiple solutions, but basically using a .filter() like clause somewhere should do it.
Like (0 to 10).filterNot(_ == 3).foreach(doStuff()) for example
Related
I am doing some of CodeWars challenges recently and I've got a problem with this one.
"You are given an array (which will have a length of at least 3, but could be very large) containing integers. The array is either entirely comprised of odd integers or entirely comprised of even integers except for a single integer N. Write a method that takes the array as an argument and returns this "outlier" N."
I've looked at some solutions, that are already on our website, but I want to solve the problem using my own approach.
The main problem in my code, seems to be that it ignores negative numbers even though I've implemented Math.abs() method in scala.
If you have an idea how to get around it, that is more than welcome.
Thanks a lot
object Parity {
var even = 0
var odd = 0
var result = 0
def findOutlier(integers: List[Int]): Int = {
for (y <- 0 until integers.length) {
if (Math.abs(integers(y)) % 2 == 0)
even += 1
else
odd += 1
}
if (even == 1) {
for (y <- 0 until integers.length) {
if (Math.abs(integers(y)) % 2 == 0)
result = integers(y)
}
} else {
for (y <- 0 until integers.length) {
if (Math.abs(integers(y)) % 2 != 0)
result = integers(y)
}
}
result
}
Your code handles negative numbers just fine. The problem is that you rely on mutable sate, which leaks between runs of your code. Your code behaves as follows:
val l = List(1,3,5,6,7)
println(Parity.findOutlier(l)) //6
println(Parity.findOutlier(l)) //7
println(Parity.findOutlier(l)) //7
The first run is correct. However, when you run it the second time, even, odd, and result all have the values from your previous run still in them. If you define them inside of your findOutlier method instead of in the Parity object, then your code gives correct results.
Additionally, I highly recommend reading over the methods available to a Scala List. You should almost never need to loop through a List like that, and there are a number of much more concise solutions to the problem. Mutable var's are also a pretty big red flag in Scala code, as are excessive if statements.
How to increment for-loop variable dynamically as per some condition.
For example.
var col = 10
for (i <- col until 10) {
if (Some condition)
i = i+2; // Reassignment to val, compile error
println(i)
}
How it is possible in scala.
Lots of low level languages allow you to do that via the C like for loop but that's not what a for loop is really meant for. In most languages, a for loop is used when you know in advance (when the loop starts) how many iterations you will need. Otherwise, a while loop is used.
You should use a while loop for that in scala.
var i = 0
while(i<10) {
if (Some condition)
i = i+2
println(i)
i+=1
}
If you dont want to use mutable variables you can try functional way for this
def loop(start: Int) {
if (some condition) {
loop(start + 2)
} else {
loop(start - 1) // whatever you want to do.
}
}
And as normal recursion function you'll need some condition to break the flow, I just wanted to give an idea of what can be done.
Hope this helps!!!
Ideally, you wouldn't use var for this. fold works pretty well with immutable values, whether it is an int, list, map...
It lets you set a default value (e.g. 0) to the variable you want to return and also iterate through the values(e.g i) changing that value (e.g accumulator) on every iteration.
val value = (1 to 10).fold(0)((loopVariable,i) => {
if(i == condition)
loopVariable+1
else
loopVariable
})
println(value)
Example
I need to know if something is between two limits, but I keep getting the same 2 errors in playground and I can't seem to find a solution on the web. Any idea how to do this in Swift?
var upperLimit = 20
var a = 10
var lowerlimit = 5
if a > lowerlimit < upperLimit{
println(a)
}
if lowerlimit < a < upperLimit{
println(a)
}
Both of these methods give the same (2) error messages:
---> ! Non-associative operator is adjacent to operator of same precedence
--> Cannot invoke '<'with an argument of list type '($t4, #Ivalue Int)'
That's not a valid way to make the comparison. You need to check against the bounds with two comparisons:
if a > lowerlimit && a < upperLimit {
println(a)
}
Although I prefer this way using pattern recognition on a range.
if lowerlimit..<upperLimit ~= a {
println(a)
}
Note that the pattern recognition way requires the lower bound to be inclusive, so you'd need to increase the lowerLimit variable by one.
Given the following code
import std.datetime: Clock, SysTime, Duration;
SysTime[] times;
const n = 3;
foreach (i; 0..n) times ~= Clock.currTime;
is there a simpler, perhaps functional, higher order pattern with
which to achieve the same goal?
A bonus would to be, when possible, minimize copyings of the elements perhaps through some in-place construction pattern.
See also: http://forum.dlang.org/thread/yofbijaejfyftpcjdcvd#forum.dlang.org#post-yofbijaejfyftpcjdcvd:40forum.dlang.org
Update:
Ok here's my try so far:
enum arityMin0(alias fun) = __traits(compiles, fun());
auto apply(alias fun, N)(N n) if (isCallable!fun &&
arityMin0!fun &&
!is(ReturnType!fun == void) &&
isIntegral!N)
{
import std.range: iota, map;
return n.iota.map!(n => fun);
}
called as, for instance,
import std.datetime: Clock;
auto times = 3.apply!(Clock.currTime).array;
One detail left. The restriction
arity!fun == 0
evaluate to false in
auto times = 3.apply!(Clock.currTime).array;
because arity is actually either 0 and 1 here.
So arity!fun evaluates to 1 in this case because Clock.currTime takes a defaulted argument.
Maybe we need arityMin and arityMax in std.traits aswell.
In that case should I use __traits(compiles to implement arityMin?
Evaluating currTime thrice:
auto times = 3.iota.map!(n => Clock.currTime).array();
Evaluating currTime once:
auto times = Clock.currTime.repeat(3).array();
How do I do the scala equivalent of this java code
int[][] vals = new int[4][];
for (int i=0; i < vals.length; i++) {
vals[i] = new int[1 + 2*i];
}
The Array.ofDim method takes two parameters
Like this:
Array.tabulate(4)(i => Array.ofDim[Int](1 + 2 * i))
It will be much slower, however. If this code is in a critical path, you should do a while loop to make it much like in Java.
One way to do this would be:
Array.tabulate(4)(i => new Array[Int](1 + 2 * i))