Frage

I've a list of nodes (String) that I want to convert into something the following.

create X ({name:"A"}),({name:"B"}),({name:"B"}),({name:"C"}),({name:"D"}),({name:"F"})

Using a fold I get everything with an extra "," at the end. I can remove that using a substring on the final String. I was wondering if there is a better/more functional way of doing this in Scala ?

  val nodes = List("A", "B", "B", "C", "D", "F")

  val str = nodes.map( x => "({name:\"" + x + "\"}),").foldLeft("create X ")( (acc, curr) => acc + curr )
  println(str)

 //create X ({name:"A"}),({name:"B"}),({name:"B"}),({name:"C"}),({name:"D"}),({name:"F"}),
War es hilfreich?

Lösung

Solution 1

You could use the mkString function, which won't append the seperator at the end.

In this case you first map each element to the corresponding String and then use mkString for putting the ',' inbetween.

Since the "create X" is static in the beginning you could just prepend it to the result.

val str = "create X " + nodes.map("({name:\"" + _ + "\"})").mkString(",")

Solution 2

Another way to see this: Since you append exactly one ',' too much, you could just remove it.

val str = nodes.foldLeft("create X ")((acc, x) => acc + "({name:\"" + x + "\"}),").init

init just takes all elements from a collection, except the last. (A string is seen as a collection of chars here)

So in a case where there are elements in your nodes, you would remove a ','. When there is none you only get "create X " and therefore remove the white-space, which might not be needed anyways.

Solution 1 and 2 are not equivalent when nodes is empty. Solution 1 would keep the white-space.

Andere Tipps

Joining a bunch of things, splicing something "in between" each of the things, isn't a map-shaped problem. So adding the comma in the map call doesn't really "fit".

I generally do this sort of thing by inserting the comma before each item during the fold; the fold can test whether the accumulator is "empty" and not insert a comma.

For this particular case (string joining) it's so common that there's already a library function for it: mkString.

Move "," from map(which applies to all) to fold/reduce

val str = "create X " + nodes.map( x => "({name:\"" + x + "\"})").reduceLeftOption( _ +","+ _ ).getOrElse("")

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top