Print array with different deep - scala

I have this function in Scala:
def printA(A: Array[_]): Unit = {
if (A.isInstanceOf[Array[Int]]) A.foreach(t => println(t))
else A.foreach(a => printA(a))
}
I don't know, how to fix this error, that printA(a) is Any. The function accepts input Array[_]
Thanks, guys!

Maybe, it is better to check an element instead of an array?
def printA(array: Array[_]): Unit = {
array.foreach {
case i: Int => println(i)
case arr: Array[_] => printA(arr)
case unknown => sys.error("Unsupported element: "+unknown)
}
}

Related

Scala matching high order function return value

Hello im trying to use case match with a high order function. if function return true do things same for false. Thank you.
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f match
{
case true => do something
case false => do somethingelse
}
}
Looks like a good place to apply "andThen" for partial function:
Here is possibly what you need:
def funk(ls: List[Int], f: Int => Boolean): List[Int] = {
val z = f.andThen(r => r match {
case true => List(1, 2) // ..something
case false => List(3, 4) // somethingElse
})
// function application
z(5)
}
Just dig a bit around PartialFunction's:
http://www.scala-lang.org/api/current/scala/PartialFunction.html
you have to execute the function and pass the return value to the match case as
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(some integer value) match
{
case true => return a list of integers
case false => return a list of integers
}
}
for example
def funk(ls:List[Int],f:Int=>Boolean):List[Int]=
{
f(ls(0)) match
{
case true => List(1,2)
case false => List(4,3)
}
}

Map List of tuples in Scala

I am getting compile error when trying to map list of tuples. I have a method which return Future[List[(String, String)]] and I need to use those two set of String value to make a call to another method
def myHelper(): Future[List[(String, String)]] = { ... }
def myWork() = {
myHelper() map {
case(firstVal, secondVal) => otherWork(firstVal, secondVal)
}
}
Error I am getting is
found: (T1, T2)
required: List[(String, String)]
Any suggestion?
EDIT
hmm .... I wasn't clear about my question. otherWork expect list of all result
def otherWork(firstVals: List[String], secondVals: List[Strong]) = { ... }
Let's implement the myWork function as:
def myWork = myHelper.map {
helper => (otherWork _).tupled(helper.unzip)
}
Depends on what you want to do.
Call otherWork on every tuple?
def myWork() = {
myHelper().map(_.map {
case (firstVal, secondVal) => otherWork(firstVal, secondVal)
})
}
If otherWork: (String, String) => T, then myWork: () => Future[List[T]].
If otherWork: (String, String) => Future[T] and you want to run them all and collect the results, then you can use something like
def myWork() = {
myHelper() flatMap { list => Future.sequence(
list map { case (firstVal, secondVal) =>
otherWork(firstVal, secondVal)
})
}
}
With the question clarification, you want unzip.
def myWork() = {
myHelper() map { list =>
list.unzip match {
case (firstVals, secondVals) => otherWork(firstVals, secondVals)
}
}
}
Federico Pellegatta's answer has a shorter form of writing this.

Scala Overloading Issue

If I have a java.util.Map[String,Java.util.Map] for the first call, correct overloaded method is called: toScala(java.util.Map[_,_]). But in the mapValues invocation, function toScala(other:Any) is called. How to avoid this?
I would be calling toScala using a java object like Map, List, Int, String. The map may contain another java.util.Map/java.util.List/ String/Int as one of its values. Similarly the list may also contain another java.util.List/ String/ Int as its members
private def toScala(map:java.util.Map[_,_]) : Any = {
map match {
case null => Map.empty
case _ => map.asScala.mapValues(toScala).toMap
}
}
private def toScala(list:java.util.List[_]) : Any = {
list match {
case null => List.empty
case _ => list.asScala.map(toScala).toList
}
}
private def toScala(other:Any) : Any = {
other match {
case null => None
case _ => other
}
}
Maybe this helps you:
private def toScala(v: Any): Any = vmatch {
  case null => throw new NullPointerException("null value encountered while converting Java to Scala")
  case m: java.util.Map[_, _] => m.asScala.mapValues(toScala).toMap
  case m: java.util.List[_] => m.asScala.map(toScala).toMap
  case m: java.util.Set[_] => m.asScala.map(toScala).toMap
  case m => m
}
Or:
private def toScalaOption(v: Any): Any = vmatch {
  case null => None
  case m: java.util.Map[_, _] => m.asScala.mapValues(toScala).toMap
  case m: java.util.List[_] => m.asScala.map(toScala).toMap
  case m: java.util.Set[_] => m.asScala.map(toScala).toMap
  case m => Some(m)
}
Cheers

Scala matching, resolving the same variable from two different patterns

Say I have the following
case class IntWrap(value:Int)
I would like to extract the same variable from two cases as follows:
x match {
case value:Int | IntWrap(value) => dosomethingwith(x)
case _ => ???
}
but the only way I have been able to do this is as:
x match {
case value:Int => dosomethingwith(x)
case IntWrap(value) => dosomethingwith(x)
case _ => ???
}
Is there a better way, as in my real life case dosomething is actually a large block of code which is not so easy to encapsulate.
If it is really the case that you want to do something with x, not with the extracted value, then the following would work:
case class IntWrap(value:Int) // extends T
def dosomethingwith(x: Any) = x
val x: Any = IntWrap(101)
x match {
case _: Int | _: IntWrap => dosomethingwith(x)
case _ => ???
}
If you actually want to work with the extracted value, you could factor out the corresponding match block into its own extractor and reuse that wherever necessary:
x match {
case Unwrap(value) => dosomethingwith(value)
case _ => ???
}
object Unwrap {
def unapply(x: Any) = x match {
case x: Int => Some((x))
case IntWrap(value) => Some((value))
case _ => None
}
}
I honestly don't see an issue with the way you are doing things. As long as dosomethingwith is a separate function then I don't see any issues with duplicate code. If your code looked like this then I don't see any need to come up with other solutions:
def foo(x:Any){
x match {
case value:Int => dosomethingwith(value)
case IntWrap(value) => dosomethingwith(value)
case _ => ???
}
}
def dosomethingwith(x:Int){
//do something complicated here...
}
I came up with sth a little bit different, but it may help you avoid duplicates:
case class IntWrap(value: Int)
implicit def intWrapToInt(intWrap: IntWrap) = intWrap.value
def matchInt(x: AnyVal) = x match {
case i: Int => println("int or intWrap")
case _ => println("other")
}
//test
matchInt(IntWrap(12)) //prints int or intWrap
matchInt(12) //prints int or intWrap
matchInt("abc") //prints other
It won't work for every reference, though. So, be careful.

How to pattern-match Class[X] for different X?

I want to check the type of the parameters of a method, but I don't know the best way to do this. See my code:
class X {
def x(a: Int, b: String) {}
}
val methods = classOf[X].getDeclaredMethods
methods map { m =>
m.getParameterTypes.toList map { t =>
println(t.getName)
// I don't know how to write the following
if ( the type of t is Int) { do something}
else if( the type of t is String ) { do something}
else { }
}
}
Please note the comment in the code. I don't know how to check the types in scala way.
I've tried:
t match {
case _:String => println("### is a string")
case _:Int => println("### is an int")
case _ => println("### ?")
}
But it can't be compiled.
I can use java-way to check:
if (t.isAssignableFrom(classOf[String])) // do something
else if(t.isAssignableFrom(classOf[Int])) // do something
else {}
It seems we should use it in scala, right?
UPDATE:
If I want to use match, I should write like this:
t match {
case i if i.isAssignableFrom(classOf[Int]) => println("### is an Int")
case s if s.isAssignableFrom(classOf[String]) => println("### is a String")
case _ => println("###?")
}
Is it the best answer?
I could make it work with t as a type by defining the cases as constants. It wouldn't compile with the class literals as the case expression. Try:
val S = classOf[String]
val I = classOf[Int]
t match {
case S => println("### is a string")
case I => println("### is an int")
case _ => println("### ?")
}
You can use ClassManifest.fromClass to correctly handle the coercion of primitives to AnyVals, and any other such troubles you might have encountering boxed vs unboxed types when getting funky with reflection.
Like this:
import reflect.ClassManifest
class Wibble { def method(a:Int, b: String) = () }
for(method <- classOf[Wibble].getDeclaredMethods; paramType <- method.getParameterTypes) {
ClassManifest.fromClass(paramType) match {
case m if m <:< ClassManifest.Int => println("Interiffic")
case m if m <:< ClassManifest.Float => println("Floaty, like butterflies")
case m if m <:< ClassManifest.Double => println("Or Quits...")
//todo: all the other AnyVal types...
case m if m <:< classManifest[String] => println("bleeding edge physics, yeah baby!")
//...and a default condition
}
}