Array.Add vs + =


179

PowerShell Arrays에서 배열을 다음과 같이 선언하면 흥미로운 동작을 발견했습니다.

$array = @()

그런 다음 $array.Add("item")방법을 사용하여 항목을 추가하려고 하면 다음 오류가 발생합니다.

"1"인수와 함께 "Add"호출 예외 : "Collection의 크기가 고정되었습니다."

그러나를 사용하여 항목을 추가 $array += "item"하면 문제없이 항목이 허용되며 "고정 크기"제한이 적용되지 않는 것 같습니다.

왜 이런거야?

답변:


254

$array.Add()-method를 사용할 때 기존 배열에 요소를 추가하려고합니다. 배열은 고정 된 크기의 모음이므로 확장 할 수 없기 때문에 오류가 발생합니다.

$array += $element이전 항목 + 새 항목과 동일한 요소로 배열을 작성 하고이 새 큰 배열은 $array-variable 에서 이전 항목을 대체합니다.

+ = 연산자를 사용하여 배열에 요소를 추가 할 수 있습니다. 이를 사용하면 Windows PowerShell은 실제로 원래 배열의 값과 추가 된 값으로 새 배열을 만듭니다. 예를 들어, 값이 200 인 요소를 $ a 변수의 배열에 추가하려면 다음을 입력하십시오.

    $a += 200

출처 : about_Arrays

+= 값 비싼 작업이므로 많은 항목을 추가해야하는 경우 가능한 적은 작업으로 항목을 추가해야합니다. 예 :

$arr = 1..3    #Array
$arr += (4..5) #Combine with another array in a single write-operation

$arr.Count
5

이것이 가능하지 않은 경우 List또는 보다 효율적인 콜렉션을 사용하는 것이 ArrayList좋습니다 (다른 답변 참조).


고마워 :) 이런 식으로 생각했지만 큰 배열에서는 비효율적이라고 생각했기 때문에 powershell 팀은 다른 일을하고있었습니다.
malgca

6
맞습니다. 큰 배열에서는 비효율적입니다. 불행히도이 문제를 해결하려면 다른 유형을 사용해야합니다. powershell.org/wp/2013/09/16/…
Nacht

3
때에 따라 다르지. 당신이 추가 한 다음 예 회원을 많이 제거하려는 경우, 시도 ListArrayList. 그들은 훨씬 더 빠를 것입니다. 나는 +=보통 여분의 초가 중요하지 않은 짧은 버리기 스크립트를 생성하기 때문에 개인적으로 시간의 99 %를 사용 하고 배열합니다. 내가 사용하는 시간을 최적화하고 절약하려는 위치에 추가 / 제거가 많은 큰 스크립트의 경우 List또는 ArrayList.
Frode F.

3
배열의 크기는 항상 고정되어 있으므로 왜 Add()메소드가 존재 하는지 아는 사람 이 있습니까?
JohnLBevan

4
에서 상속되었으므로 IList. 시도는 Get-Member -InputObject @()이 표시됩니다Add Method int IList.Add(System.Object value)
프로 데 F.에게

113

동적 크기의 배열을 원한다면 목록을 만들어야합니다. .Add()@ frode-f에서 설명한 것처럼 기능 을 사용할 수있을뿐만 아니라 동적 배열은 메모리 효율성이 높고 더 나은 방법입니다.

그리고 사용하기 매우 쉽습니다.

배열 선언 대신 다음을 시도하십시오.

$outItems = New-Object System.Collections.Generic.List[System.Object]

항목을 추가하는 것은 간단합니다.

$outItems.Add(1)
$outItems.Add("hi")

그리고 당신이 정말로 배열을 원한다면, 그 기능도 있습니다.

$outItems.ToArray()

1
나는 이것을 시도했다. New-Object System.Collections.Generic.List [string]을 사용하여 생성하지만 .GetType을 수행하면 배열임을 알려줍니다.
Preza8

1
Add()기능을 사용해 보셨습니까 ? List위에서 언급 한 것처럼 일반 객체 를 만들면 Add()Remove()메소드를 사용하여 항목을 추가하고 제거 할 수있는 변경 가능한 목록이 있음을 확인할 수 있습니다 .
벤더 더 위대한

1
@ Preza8 : 예상대로 나에게 (New-Object System.Collections.Generic.List[string]).GetType().Name수율 List`1; 아마도 메서드를 +=호출하지 않고 목록을 포함하는 변수에 적용했을 수 있습니다 .Add().이 경우 변수 값은 실제로 배열 ( System.Object[]) 로 변환됩니다 .
mklement0

바로 가기 :$a = new-object collections.generic.list[object]
Andrew

4

비효율적 인 배열을 사용하지 않고 배열을 만드는 가장 일반적인 관용구 +=는 루프 출력에서 ​​다음과 같습니다.

$array = foreach($i in 1..10) { 
  $i
}
$array
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.