Copying a list of strings to a list of a class made out of strings

Hello there,

now my question title probably sounds really confusing but I hope I can clear that up with a bit of code!

	def transfer_lists(old_list: List[Identifier], new_list: List[String]) : List[String] = {
	if(old_list.isEmpty)
		return new_list
	else
		new_list.::(old_list.head.toString)
		transfer_lists(old_list.tail, new_list)
	}

//Identifier from List[Identifier] is
//class Identifier (id: String)
//This function returns an empty list
//Probably because I call it with an empty list and nothing changes

So the function transfer_lists gets 2 lists, as parameters, and it aims to copy the elements from the old list to the new list. The problem is, that the old list consists of class elements, which are basically strings.

I need to convert the list with the class elements to a list containing only strings and I don’t know what I am doing wrong here and how else I could achieve that.

Thanks in advance for any help!

List is an immutable data structure. When you invoke newElement :: someList you create a new List consisting of all elements of someList with newElement prepended. someList stays unchanged.

1 Like

Thanks you very much, Jasper!

I changed the else to

else{
	val new_new_list: List[String] = new_list.::(old_list.head.toString)
	transfer_lists(old_list.tail, new_new_list)
}

This compiles now and seems to work :slight_smile:

I have a follow up question if you don’t mind.

Even though I declared val new_new_list as List[String] the function returns a List of Type List(Identifier). Would you know a way to convert it to a List[String]?
Edit: The conversion from to List was the motivation of making the function in the first place.

Thank you!

I’m guessing that you are printing out the result of transfer_lists and it printed something like List(Identifier(a),Identifier(b))? Identifier is probably a case class. The toString method of a case class returns a String containing their name followed by their members between parentheses. If you want a List(a,b) instead you should replace old_list.head.toString with old_list.head.id.

A few other pointers:

  • In Scala you almost never have to use the return keyword.
  • Methods ending with : are special. If you use them as infix operators they are called on the right operand. So tail.::(head) and head :: tail are equivalent. In that case I think the infix style is always preferred.
  • Creating a new List containing a transformation of every item in the first List is basically a map. You could rewrite that code into
def transfer_list(oldList: List[Identifier]): List[String] =
  oldList.map(ident => ident.id)

Or even shorter:

def transfer_list(oldList: List[Identifier]): List[String] =
  oldList.map(_.id)
1 Like

Yes, everything correct. [quote=“Jasper-M, post:4, topic:532”]
The toString method of a case class returns a String containing their name followed by their members between parentheses. If you want a List(a,b) instead you should replace old_list.head.toString with old_list.head.id.
[/quote]

Oh, I didn’t know that difference! I tried your alternative and it works perfectly fine, thanks!

I also appreciate your other points, I will take them into consideration.

Thanks for your detailed answers, Jasper.
Cheers, Felix