0

Having as Input a list of String (one of them could be None). How can I return a Array of String using Immutable Object.

It's pretty easy if I use var or Mutable Object, here an example:

def getArrayString(string: String, list1: List[String], list2: Option[List[String]]): Array[String] = {
  var ret = Array[String]()
  ret = ret :+ string
  if (list1.nonEmpty) {
    for (item <- list1) {
      ret = ret :+ item
    }
  }
  if (list2.isDefined) {
    for (item <- list2.get) {
      ret = ret :+ item
    }
  }
  ret
}

Question1: What if I want to use just val object?

N.B.: if list2 is None the returning array should not have any None Object

Question2: ..and if list1 and list2 were List[CustomClass] where CustomClass is

case class CustomClass(string:String)

How would you do?

Question3: ...What if we complicate the method with...

case class CustomClass1(string1:String)

case class CustomClass2(string2:String)

obviously CustomClass1 and CustomClass2 might have some other parameters in their class that make them different from each other. The signature of the method would be then:

def getArrayString( string: String
                , list1: List[CustomClass1]
                , list2: Option[List[CustomClass2]]
              ): Array[String]`
2
  • 2
    (string :: list1 ::: list2.getOrElse(Nil)).toArray Commented Jan 10, 2017 at 16:13
  • 1
    If CustomClass is the same for both lists, you can map it just once at the end Commented Jan 10, 2017 at 18:55

2 Answers 2

1

You can use :: which will prepend an element to a list, and ++ which will concatenate 2 lists:

val ret = (string :: (list1 ++ list2.getOrElse(Nil))).toArray

For the updated version:

val ret = (string :: (list1 ++ list2.getOrElse(Nil)).map(_.string)).toArray
Sign up to request clarification or add additional context in comments.

5 Comments

In a hurry to answer first you got a compilation error :) Move brackets to include string variable.
@tkachuko Updated
Nitpick: mixing :: and ++ seems a bit weird to me — I would either use :: and :::, or +: and ++. One is the List API, the other is the Seq API (which also works for Lists).
@SethTisue, why is it weird? is it inefficient?
The differently-named methods do the same thing, there's no efficiency difference. It's no big deal, it just reads a bit oddly to me to mix and match the two APIs.
1

Every time I see Option I think "fold?".

def getArrayString( string: String
                  , list1: List[String]
                  , list2: Option[List[String]]
                  ): Array[String] =
  list2.foldLeft(string +: list1)(_++_).toArray

update (as requested)

case class CustomClass(string:String)
def getArrayString( string: String
                    , list1: List[CustomClass]
                    , list2: Option[List[CustomClass]]
                  ): Array[String] =
  string +: list2.foldLeft(list1)(_++_).map(_.string).toArray

Or the slightly more concise:

  Array(string) ++ (list1 /: list2)(_++_).map(_.string)

9 Comments

Thank you jwvh, but this doesn't work if list2 is None and it is less readable than Alvaro's answer
Really? What should be returned if list2 is None?
It has to return an Array of String.. EDIT: I did some testing and yes. Your code return what it should :)
I edited the question, could you extend your answer please?
Thank you, really appreciate it! ... but if CustomClass (say CustomClass1 and CustomClass2, respectively for list1 and list2) is not the same for both lists, this would not work though
|

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.