0
def f(c: String) = {
  val array = ("google.com|yahoo.com|gmail.com|mail.com").split("\\|")
  for (i <- array) {
    if (c.contains(i)) {
      println("comparing " + c + " with " + i)
      i
    }
  }
  "N/A"
}

My intention for the above function is that, it will return N/A if c does not contain any of the elements of the array. And, if it does, it will return the element in the array. So if c="www.google.com/1234" , ideally the function would return google.com and if c="bloomberg.com/example", the function will return N/A.

But when I do println(f("www.google.com/1234")) I get N/A. Can anyone tell me what am I doing wrong.

1
  • The for() statement goes through the entire array. After it's finished the program moves to the next line: "N/A" Since that's the last line of the method, that's what the method returns, no matter what happens in the for().. Commented Mar 20, 2018 at 0:35

2 Answers 2

2

Your function always returns N/A, because it's the last value in its definition. To leave a value in the end like this means in Scala the same as writing return "N/A". But even without N/A in the end, your function wouldn't return what you want, because:

  1. the last statement would be for { ... } which is of type Unit
  2. your function is side-effecting, by calling println, it's not the same as returning a value

Let's write first a function that tries to find a match:

def findMatch(c: String): Option[String] = {
  val array = "google.com|yahoo.com|gmail.com|mail.com".split('|')
  array.find(c.contains)
}

Notice that the return type is Option[String] which comes from the call to the find method. Now you can use it to print the result if it's there or N/A otherwise:

def f(c: String): Unit = {
  println(findMatch(c).getOrElse("N/A"))
}
Sign up to request clarification or add additional context in comments.

Comments

0

While laughedelics solution looks fine, another one, on your track, is possible too:

def f (c: String) : List[String] = {
  val array = ("google.com|yahoo.com|gmail.com|mail.com").split("\\|")
  val list = (for (i <- array 
    if (c.contains(i))) yield {
      println("comparing " + c + " with " + i)
      i
    }).toList
  if (list.isEmpty) List ("N/A") else list
}

It prints while iterating and either returns a list of matches, or a List with the String "N/A", which should, in practice, in most cases result in a List of exactly one String, not less or more, but depending on the input, more than one match is possible.

scala> f ("www.google.com/1234")
comparing www.google.com/1234 with google.com
res61: List[String] = List(google.com)

scala> f ("www.göögle.com/1234")
res62: List[String] = List(N/A)

scala> f ("www.google.com/1234?param:subject='mail.com'")
comparing www.google.com/1234?param:subject='mail.com' with google.com
comparing www.google.com/1234?param:subject='mail.com' with mail.com
res63: List[String] = List(google.com, mail.com)

The main difference to your approach is the use of a yield, to return something from the for-construct.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.