2014-07-15 14 views
9

Tôi đang vật lộn một chút để loại bỏ dòng đầu tiên (ID mục) của một mảng.PowerShell Xóa mục [0] khỏi một mảng

$test.GetType() 

IsPublic IsSerial Name          BaseType                          
-------- -------- ----          --------                          
True  True  Object[]         System.Array 

Để liệt kê tất cả các tùy chọn tôi đã cố gắng ,$test | gm và nó nêu rõ:

Remove   Method    void IList.Remove(System.Object value)                        
RemoveAt  Method    void IList.RemoveAt(int index) 

Vì vậy, khi tôi cố gắng $test.RemoveAt(0) tôi nhận được lỗi:

Exception calling "RemoveAt" with "1" argument(s): "Collection was of a fixed size."At line:1 char:1 
+ $test.RemoveAt(1) 
+ ~~~~~~~~~~~~~~~~~ 
    + CategoryInfo   : NotSpecified: (:) [], MethodInvocationException 
    + FullyQualifiedErrorId : NotSupportedException 

Vì vậy, cuối cùng tôi đã tìm thấy here rằng mảng của tôi cần phải thuộc loại System.Object để có thể sử dụng $test.RemoveAt(0). Có cách nào tốt nhất để khai báo tất cả các mảng trong phần đầu của tập lệnh dưới dạng danh sách? Hoặc là tốt hơn để chuyển đổi các mảng với $collection = ({$test}.Invoke()) vào danh sách sau này khi chức năng này là cần thiết?

Ưu và khuyết điểm của cả hai loại là gì? Cảm ơn sự giúp đỡ của bạn.

Trả lời

15

Mảng có kích thước cố định, như lỗi nói. RemoveAt() là phương pháp được kế thừa không áp dụng cho các mảng thông thường. Để loại bỏ các mục nhập đầu tiên trong mảng, bạn có thể ghi đè lên các mảng bởi một bản sao trong đó bao gồm tất cả các mục trừ người đầu tiên, như thế này:

$arr = 1..5 

$arr 
1 
2 
3 
4 
5 

$arr = $arr[1..($arr.Length-1)] 

$arr 
2 
3 
4 
5 

Nếu bạn cần phải loại bỏ các giá trị tại các chỉ số khác nhau thì bạn nên xem xét sử dụng một List. Nó hỗ trợ Add(), Remove()RemoveAt():

#If you only have a specific type of objects, like int, string etc. then you should edit `[System.Object] to [System.String], [int] etc. 
$list = [System.Collections.Generic.List[System.Object]](1..5) 

$list 
1 
2 
3 
4 
5 

$list.RemoveAt(0) 

$list 
2 
3 
4 
5 

Xem của tôi trước đó SO answerabout_Arrays để biết thêm chi tiết về cách các mảng công việc.

1

Tôi nghĩ nó sẽ phụ thuộc vào hoàn cảnh. Nếu bạn chỉ cần loại bỏ yếu tố đầu tiên một lần, sau đó bạn có thể sử dụng mảng cắt:

$arr = $arr[1..($arr.length-1)] 

Nếu bạn đang đi để làm điều đó nhiều lần, sau đó bạn nên bắt đầu với một ArrayList hoặc bộ sưu tập chung. Nếu đó là một mảng lớn, bạn có thể muốn chỉ cần đặt biểu thức tạo nó vào một scriptblock và làm một .invoke() trên đó thay vì để cho đường ống tạo một mảng và sau đó chuyển đổi nó thành một tập hợp.

0

Xin lỗi câu trả lời muộn, nhưng tôi cũng đang phải vật lộn với điều này. Đối với ý định và mục đích của tôi (viết vào một tập tin văn bản), tôi nhận ra rằng kể từ khi mảng là một kích thước cố định - thay vì loại bỏ nó tôi chỉ có thể thiết lập giá trị cho string.empty.

$results = SQLQuery -connectionString $connectionString -query $query; 
$results[0] = ''; 
foreach ($r in $results) { 
    Add-Content $skus $r[0]; 
} 

Đối với tôi, điều này đã loại bỏ tiêu đề mà tôi không muốn trong tệp phẳng của mình. Hy vọng điều này sẽ giúp người khác ra khỏi đó.

2

Chỉ cần cập nhật - có một vấn đề với @Frode F. answer

If the number of elements in array is more than 1

$arr = $arr[1..($arr.Length-1)] 

If the number of elements is 1, then this doesn't remove the element

if($arr.Length -le 1) { 
    $arr = @() 
} 
else { 
    $arr = $arr[1..($arr.length - 1)] 
} 
7

này sẽ cho phép bạn loại bỏ tất cả các lần xuất hiện của một phần tử tùy ý từ một mảng mà không cần đến một tinh vi hơn Đối tượng .NET.

$x=<array element to remove> 
$test = $test | Where-Object { $_ -ne $test[$x] } 

Điều này sẽ làm tương tự, nhưng sẽ chỉ xóa một trong các thành phần. Nếu có bản sao, chúng sẽ vẫn còn.

$x=<array element to remove> 
$skip=$true 
$test = $test | ForEach-Object { if (($_ -eq $x) -and $skip) { $skip=$false } else { $_ } } 
+0

Được thăng hạng, điều này đã thực hiện mẹo cho tôi. Và nó đẹp và súc tích. – Spikee

+0

Điều này có thể hoạt động không đúng nếu mảng chứa giá trị trùng lặp. –

+0

@RonMacNeil, điểm tốt. Tôi đã cập nhật câu trả lời của mình. –

Các vấn đề liên quan