1

I would like to add element of a list at the end of every element of another list.

I have :

val Cars_tmp :List[String] = List("Cars|10|Paris|5|Type|New|", "Cars|15|Paris|3|Type|New|")
=> Result : List[String] = List("Cars|10|Paris|5|Type|New|", "Cars|15|Paris|3|Type|New|")

val Values_tmp: List[String] = a.map(r =>  ((r.split("[|]")(1).toInt)/ (r.split("[|]")(3).toInt)).toString ).toList
=> Result : List[String] = List(2, 5)

I would like to have the following result (first element of Values_tmp is concatenate with first element of Cars_tmp, second element of Values_tmp is concatenate with second element of Cars_tmp...) like below:

 List("Cars|10|Paris|5|Type|New|2", "Cars|15|Paris|3|Type|New|5")

I tried to do this:

Values_tmp.foldLeft( Seq[String](), Cars_tmp) { case ((acc, rest), elmt) => ((rest :+ elmt)::acc) }

I have the following error:

console>:28: error: type mismatch;
found   : scala.collection.immutable.IndexedSeq[Any]
required: List[String]

Than you for your help.

fleur
  • 29
  • 5
  • 1
    You could use `zip` and `map` to do this too (and it would probably be easier) – user Oct 06 '20 at 13:27
  • 1
    Also, I would recommend you to parse your TSV data into a **case class** to ease the process of manipulate it. – Luis Miguel Mejía Suárez Oct 06 '20 at 13:30
  • @user, Thank you for your answer. I tried with map and zip but it does not work. How will you do that ? – fleur Oct 06 '20 at 14:03
  • 1
    `Cars_tmp.zip(Values_tmp).map{case (car, value) => car + value}` – user Oct 06 '20 at 14:17
  • @user: Thank you. It works. Have you an idea with using foldLeft ? I don't understand my error: found : scala.collection.immutable.IndexedSeq[Any] required: List[String] – fleur Oct 06 '20 at 14:30

1 Answers1

1

Try to avoid zip, it "fails" silently when the iterables do not have the same size. (In your code, it seems obvious that the 2 lists have the same size, but for more complex code, this is not obvious.)

You can compute the "value" you need and concatenate it on the fly:


val Cars_tmp: List[String] = List("Cars|10|Paris|5|Type|New|", "Cars|15|Paris|3|Type|New|")

def getValue(str: String): String = {
    val Array(_, a, _, b, _, _) = str.split('|')  // Note the single quote for the split. 
    (a.toInt / b.toInt).toString
}

Cars_tmp.map(str => str + getValue(str))

I proposed an implementation of getValue using the unapply of Arrays, but you can keep your implementation !

def getValue(r: String) = ((r.split("[|]")(1).toInt)/ (r.split("[|]")(3).toInt)).toString
BlueSheepToken
  • 5,751
  • 3
  • 17
  • 42
  • @fleur, my pleasure! Do not hesitate to accept the answer if it completely answers your question – BlueSheepToken Oct 07 '20 at 12:27
  • it's accepted. Have you got an idea if I want to do this with foldLeft? or foldRight? – fleur Oct 07 '20 at 13:42
  • 1
    You probably want to use a foldRight, to avoid a full copy of your list each time you add an element. The idea would be the following: `Cars_tmp.zip(Values_tmp).foldRight(List[String]()) {case ((car, value), acc) => (car + value) :: acc}`. However, this would fail silently for unequal lengths lists :) – BlueSheepToken Oct 07 '20 at 14:36