I have this method
def example(something):something {
val c=List()
if(){
if(){
val a=List()
}
else{
val a=List()
}
}
//here a or b are not declared
c:::a
}
How to declare it and make it visible? I can not use var.
You can't make it visible outside declaration scope, so, maybe, try this:
def example(somthing):somthing{
val c = {
if (something) {
(0 to 10).toList
} else {
(0 to 5).toList
}
}
}
Almost Everything in Scala returns a value (the exception is for statements such as package declarations and imports)
if/else statements, pattern matches, etc. etc.
This means that your if/else block returns a value, and is especially keen to do so, very much like the ?: ternary operator in Java.
val foo = ... some integer ...
val bar = if(foo >= 0) "positive" else "negative"
Or using blocks:
val foo = ... some integer ...
val bar = if(foo >= 0) {
"positive"
} else {
"negative"
}
Nest 'em to your heart's content if you wish!
val foo2 = ... some other integer ...
val bar = if(foo >= 0) {
if(foo2 >= 0) {
"double positive"
} else {
"part-way there"
}
} else {
"foo was negative"
}
and even mix 'n' match styles:
println(
if(foo >= 0) {
if(foo2 >= 0) "double positive" else "part-way there"
} else {
"foo was negative"
}
)
In your particular case, you do not need the val a:
def example(something):something {
val c= yourListC ::: if(firstTest){
if(secondTest){
yourListA
}
else{
yourOtherListA
}
} else {
anAdequateEmptyList
}
}
Related
I'm trying to implement a streaming process on Kafka. The data structure that I'm using looks like this one:
trait Base {def baseField: String}
final case class Elem0(baseField: String, oil: String, oil2: String) extends Base
final case class Elem1(baseField: String, engine: String, engine2: String) extends Base
final case class Elem2(baseField: String, tire: String, tire2: String) extends Base
This is just a simplification, the real "ElemX" classes (and the Base) have many more fields. The main App receives different objects of each of the classes using different Kafka topics. Each object needs to be processed independently.
I need to implement a function that does some complicated logic depending on the values of the fields of "ElemX". The possible values of "oil", "engine" and "tire" are the same for all classes (let's say that they can be "X", "Y", "Z"). I mean, there are just 3 possible values for all the case classes' fields. So my first approach is something like this:
def doSomethingWithElem0(record: Elem0) = {
if (record.oil == "X") {
... // logic1
} else if (record.oil == "Y") {
... // logic2
} else {
... // logic3
}
if (record.oil2 == "X") {
... // logic1
} else if (record.oil2 == "Y") {
... // logic2
} else {
... // logic3
}
...
}
def doSomethingWithElem1(record: Elem1) = {
if (record.engine == "X") {
... // logic1
} else if (record.engine == "Y") {
... // logic2
} else {
... // logic3
}
if (record.engine2 == "X") {
... // logic1
} else if (record.engine2 == "Y") {
... // logic2
} else {
... // logic3
}
...
}
def doSomethingWithElem2(record: Elem2) = {
if (record.tire == "X") {
... // logic1
} else if (record.tire == "Y") {
... // logic2
} else {
... // logic3
}
if (record.tire2 == "X") {
... // logic1
} else if (record.tire2 == "Y") {
... // logic2
} else {
... // logic3
}
...
}
As you can see there is a lot of duplicated logic but it all depends on the values of the case class fields. I cannot have something like this:
if (record.tire == "X" || record.tire2 == "X") {
// logic1
}
Because the logic involves doing something with each of the field values. This logic involves checking that specific value on a Redis database and things like checking the last time a certain value was received (for instance, I need to check if the value of record.tire was stored previously and do some calculations based on this). The key point is that I want to "apply" the same logic for all the case class fields without having to go over each record.field
Is there any way I could simplify this logic? I've been checking libraries like shapeless but I don't know if I can apply this kind of functions here.
Any help would be greatly appreciated.
Well, case classes are Products, so if you are talking about iterating over a case class fields, and applying the same logic to them, you could do something like:
record.productIterator.tail.foreach {
case "X" => logic1()
case "Y" => logic2()
case _ => logic3()
}
I have a Scala function as shown below. Input neighborhood is array of strings. However, sometimes it (i.e. neighborhood) can be empty. In that case I get "ArrayIndexOutOfBoundsException", which is understandable. I want to avoid this exception. I mean, my code has to skip this error and move on to the next job (not shown here).
I tried this:
if(neighborhood.isEmpty){
true
} else {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
But IntelliJ shows 'type mismatch between iterator and boolean.'
How to deal with this? I am newbie in Scala. Thanks!
Here is original function:
private def scanData(neighborhood: Array[String], k: Int): Iterator[Array[String]] = {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
```scala
You can make use of headOption for a clean approach.
neighborhood.headOption.map { key =>
neighborhood.tail
.filterNot(_ == key)
.combinations(k-1)
}.getOrElse(Iterator.empty)
Use Option. You may find information here. Here you are en example :
object Run {
def main(args:Array[String]):Unit = {
val neighborhood:Array[String] = Array("1", "2","3")
val k = 1
val isa = geta(emptyArray) match {
case Some(isa) => scanData(neighborhood,k)
case None => Array.empty
}
}
def scanData(neighborhood: Array[String], k: Int): Iterator[Array[String]] = {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
def geta(neighborhood:Array[String]):Option[Array[String]] = {
if(neighborhood.isEmpty){
return None;
} else {
return Some(neighborhood)
}
}
}
I have a set of names in a file. I need to implement a Generator that iterates through them continually. However, the code is hanging indefinitely at if (iter.hasNext) after the first pass.
Gen code
var asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt")
var source: BufferedSource = Source.fromInputStream(asStream)
var iter: Iterator[String] = Iterator.continually(source.getLines()).flatten
val genLastName: Gen[String] = {
genCannedData
}
def genCannedData: Gen[String] = {
println("Generating names: " + iter)
Gen.delay {
if (iter.hasNext) {
println("In if")
Gen.const(iter.next)
}
else {
println("In else")
Gen.const(iter.next)
}
}
}
Sample Property test
property("FirstNames") = {
forAll(genLastName) {
a => {
println(a)
a == a
}
}
}
en_US_sample.txt file contents
Abbie
Abby
Abigail
Ada
Adah
EDIT- Temporary working code
The following code works if I recreate the iterator but I was wondering why Iterator.continually is hanging?
def genCannedData: Gen[String] = {
Gen.delay {
if (iter.hasNext) {
Gen.const(iter.next)
}
else {
asStream = getClass.getResourceAsStream("/firstnames/female/en_US_sample.txt")
source = Source.fromInputStream(asStream)
iter = source.getLines()
Gen.const(iter.next)
}
}
}
After first iteration, an iterator returned by source.getLines() returns false for hasNext, which means an empty iterator.
Iterator.continually() continually evaluate source.getLines() expecting a next iterator, but it continues to return an empty iterator. Then it forms an infinite loop.
My code throw exception scala.util.control.BreakControl, but I don't know why. Does anyone know?
Some place I use breakable and break, but I don't why cause this exception.
fragment 1
breakable {
for (quaOfLine <- dataOfLine) {
try {
// ... some other code
if (judgeTime(jsonQua.getInt("startTime")) == judgeTime(jsonLine.getInt("startTime"))) {
// ... some other code
if (quaRRIDs.length / RRIDs.length.toFloat >= 0.8 || quaRRIDs.length / RRIDs.length.toFloat <= 1.2) {
var count = 0
breakable {
for (rrid <- RRIDs) {
for (quaRRID <- quaRRIDs) {
if (rrid == quaRRID) {
count += 1
break //break
}
}
}
}
if (count / RRIDs.length.toFloat >= 0.8) {
sameLine = qualifier + "::" + value
break // break
}
}
}
} catch {
case e: Throwable => e.printStackTrace
}
}
}
fragment 2
breakable {
for (quaOfDest <- dataOfDest) {
try {
val qualifier = quaOfDest.getString("qualifier")
val value = quaOfDest.getString("value")
val jsonQua = new JSONObject(value)
val (quaSLon, quaSLat, quaELon, quaELat) = getSELonLat(jsonQua)
if (jsonQua.getInt("timeBucket").toString == judgeTime(jsonLine.getInt("startTime"))) {
someDest = qualifier + "::" + value
break //break
}
} catch {
case e: Throwable => e.printStackTrace
}
}
}
scala.util.control.BreakControl is thrown by the method scala.util.control.Breaks.break. It is used for simulating the break statement from Java. It is used like this:
import scala.util.control.Breaks.{break, breakable}
breakable {
for(i <- 1 until 10) {
println(i)
if(i > 5) break
}
}
BreakControl is a private class so normally it won't be thrown by anything else than break.
This also means that inside a breakable block you shouldn't catch BreakControl yourself. You break inside a try block and then catch all Throwables and print them. BreakControl is a Throwable so it will be caught by you instead of by the breakable method.
If you really want to catch all Exceptions/Throwables, you should do something like this:
import scala.util.control.Breaks.{break, breakable}
import scala.util.control.ControlThrowable
breakable {
for(i <- 1 until 10) {
try {
println(i)
if(i > 5) break
} catch {
case c: ControlThrowable => throw c
case t: Throwable => t.printStackTrace
}
}
}
The Scala Standard Library also includes a special construct for cases like this which lets you catch all Throwables except for fatal ones like OutOfMemoryError or StackOverflowError, and also everything that extends ControlThrowable:
import scala.util.control.NonFatal
try {
//do stuff
} catch {
case NonFatal(e) => e.printStackTrace
}
With the following definitions:
class Test {
var activated: Boolean = false
}
def maybeTest(): Test = {
if(...) {
val res = new Test
if(...) res.activated = true
} else null
}
I am having a lot of if structures like this one:
val myobject = maybeTest()
if(myobject != null && myobject.activated) {
// Do something that does not care about the object
}
I would like to condensate it a little bit. Is there a nice way to define/write something like this to avoid a nullPointerException:
if(maybeTest() &&> (_.activated)) {
...
}
What is a best way of achieving this in scala?
You can wrap such code in Option like this:
class Test(num: Int) {
def someNum = num
}
val test: Test = null
Option(test).map(t => t.someNum)
In this example if your variable is null then you will get None, otherwise just work with Some(value)
Update
If you don't want to use Option, then you can define such function
class Test(num: Int) {
def give = num
}
def ifDefAndTrue[T, K](obj: T)(ifTrue: T => Boolean)(then: => K) {
if (obj != null && ifTrue(obj))
then
}
In your case this look like this:
val test = new Test // assuming that activated is false
ifDefAndTrue(test)(_.activate) {
println("results in unit")
}
But it contains side effect and not functional
How about
for {m <- Option(maybeTest())
if m.activated
}
{
... // do something with non-null, activated, m
}
Found the best way with implicit classes, which properly handles the null case (although it might not be the most efficient way).
implicit class CheckNull[T](obj: T) {
def call(f: T => Unit): Unit = if(obj != null) f(obj) else ()
def is(f: T => Boolean): Boolean = if(obj != null) f(obj) else false
}
So I can write a type safe method and even calls:
if(maybeTest() is (_.activated)) {
...
}
myObjectMaybeNull call (_.pause())
Note that parenthesis around (_.activated) are necessary.