스칼라에서 목록 끝에 요소 추가


223

어리석은 질문처럼 들리지만 인터넷에서 찾은 것은 쓰레기였습니다. 단순히 type 요소를 Tlist에 추가 할 수 없습니다 List[T]. 나는 시도 myList ::= myElement했지만 이상한 객체를 만들고 액세스하여 myList.last항상 목록에 넣은 첫 번째 요소를 반환하는 것 같습니다 .

답변:


394
List(1,2,3) :+ 4

Results in List[Int] = List(1, 2, 3, 4)

이 연산의 복잡도는 O (n)입니다. 이 작업이 자주 필요하거나 긴 목록의 경우 다른 데이터 형식 (예 : ListBuffer)을 사용하는 것이 좋습니다.


7
O (2 * n)가 없으며 점근 적 복잡성에 대해 상수 요소가 무시됩니다. 나는가로 List변환되고 ListBuffer요소가 추가되고 ListBuffer다시 변환 되어 (Java String와 거의 비슷하게 StringBuilder) 생각하지만 그것은 단지 추측 일뿐입니다.
Landei

2
마지막 요소 포인터에 도달하고 마지막 요소 포인터가 가리키는 요소를 추가하려면 목록을 완전히 탐색해야하기 때문에 O (n)입니다.
pisaruk

39
@pisaruk이 경우 머리와 꼬리에 대한 포인터를 유지할 수 있습니다. 그러나 scala목록 은 변경할 수 없습니다. 즉, 목록의 마지막 요소를 "수정"하려면 먼저 복사본을 만들어야합니다. O (n) 인 사본-목록 자체의 순회가 아닙니다.

2
나는 O (n)이 간단하기 때문에이 새로운 목록 생성 믿는다
라파엘 로시

3
cons 연산자는 목록의 "의도 된"면에서 작동하므로 복잡도 O (1)이 있습니다.
Landei

67

최소한 불변 목록을 사용하여 수행해서는 안되기 때문입니다. 실제로 데이터 구조의 끝에 요소를 추가해야 하고이 데이터 구조가 실제로 목록이어야 하고이 목록이 실제로 변경 불가능 해야하는 경우 다음을 수행하십시오.

(4 :: List(1,2,3).reverse).reverse

또는:

List(1,2,3) ::: List(4)

고마워요! 바로 내가 찾던 것이 었습니다. 나는 당신의 대답에서 그렇게하지 말아야한다고 생각합니다 ... 내 구조를 수정하고 내가 할 수있는 것을 볼 것입니다. 다시 감사합니다.
Masiar

6
@Masiar는 불변성과 효율적인 추가를 원할 경우 Vector를 사용합니다. 의 성능 특성 섹션을 참조하십시오 scala-lang.org/docu/files/collections-api/collections.html
Arjan Blokzijl

29
추가 할 요소가 많은 경우 "접두사를 사용하여 목록 작성 후 뒤집기"가 유용한 패턴이지만 단일 요소를 기존 목록. "double reverse"트릭은 목록을 두 번 다시 작성하는 반면 :+, 비효율적 인 경우 한 번만 다시 작성합니다.
Nicolas Payette

25

스칼라의 목록은 수정하도록 설계되지 않았습니다. 실제로 Scala에 요소를 추가 할 수 없습니다 List. 그것은이다 불변의 데이터 구조 자바 문자열처럼. 스칼라에서 "목록에 요소를 추가"할 때 실제로하는 일은 기존 List에서 새 List 를 만드는 것 입니다. (출처)

이러한 사용 사례에 목록을 사용하는 대신 ArrayBuffer또는을 사용하는 것이 좋습니다 ListBuffer. 이러한 데이터 구조에는 새로운 요소가 추가되도록 설계되었습니다.

마지막으로 모든 작업이 완료된 후 버퍼를 목록으로 변환 할 수 있습니다. 다음 REPL 예를 참조하십시오.

scala> import scala.collection.mutable.ListBuffer
import scala.collection.mutable.ListBuffer

scala> var fruits = new ListBuffer[String]()
fruits: scala.collection.mutable.ListBuffer[String] = ListBuffer()

scala> fruits += "Apple"
res0: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple)

scala> fruits += "Banana"
res1: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana)

scala> fruits += "Orange"
res2: scala.collection.mutable.ListBuffer[String] = ListBuffer(Apple, Banana, Orange)

scala> val fruitsList = fruits.toList
fruitsList: List[String] = List(Apple, Banana, Orange)

3

이것은 답변 중 하나와 비슷하지만 다른 방식입니다.

scala> val x=List(1,2,3)
x: List[Int] = List(1, 2, 3)

scala> val y=x:::4::Nil
y: List[Int] = List(1, 2, 3, 4)

2

두 개의 목록을 추가하거나 추가하거나 목록 및 배열을
추가 할 수 있습니다.

var l = List(1,2,3)    
l=l:+4 
Result : 1 2 3 4  
var ar = Array(4,5,6)    
for(x<-ar)    
{ l=l:+x}  
  l.foreach(println)

Result:1 2 3 4 5 6

추가 :

var l = List[Int]()  
   for(x<-ar)  
    { l=x::l } //prepending    
     l.foreach(println)   

Result:6 5 4 1 2 3

1
우리는 할 수 있지만 다른 답변에서 언급 한 모든 이유로 나쁜 생각이 될 것입니다.
jwvh
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.