2014-07-15 8 views
9

मैं किसी सरणी की पहली पंक्ति (आइटम आईडी) को हटाने के लिए थोड़ा संघर्ष कर रहा हूं।पावरशेल एक सरणी से आइटम [0] हटाएं

$test.GetType() 

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

सभी विकल्पों को मैं ,$test | gm की कोशिश की सूचीबद्ध करने के लिए और यह स्पष्ट रूप से कहा गया है:

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

तो जब मैं $test.RemoveAt(0) कोशिश मैं त्रुटि मिलती है:

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 

तो मैं अंत में पाया गया कि here$test.RemoveAt(0) का उपयोग करने में सक्षम होने के लिए मेरी सरणी को System.Object प्रकार की आवश्यकता है। क्या लिपि की शुरुआत में सभी सरणी को सूची के रूप में घोषित करना सबसे अच्छा अभ्यास है? या क्या इस कार्यक्षमता की आवश्यकता होने पर बाद में सूची में $collection = ({$test}.Invoke()) के साथ सरणी को परिवर्तित करना बेहतर है?

दोनों प्रकार के समर्थक और विपक्ष क्या हैं? आपके सहयोग के लिए धन्यवाद।

उत्तर

15

Arrays निश्चित आकार के हैं, जैसे कि त्रुटि कहती है। RemoveAt() एक विरासत विधि है जो सामान्य सरणी पर लागू नहीं होती है।

$arr = 1..5 

$arr 
1 
2 
3 
4 
5 

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

$arr 
2 
3 
4 
5 

आप विभिन्न अनुक्रमित में मूल्यों को दूर करने की जरूरत है तो आप एक प्रयोग करने पर विचार करना चाहिए: सरणी में पहली प्रविष्टि निकालने के लिए, आप एक प्रति है कि पहले को छोड़कर हर आइटम है, इस तरह शामिल द्वारा सरणी के ऊपर लिख सकता है List। यह समर्थन करता है 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 

कैसे सरणियों काम के बारे में अधिक जानकारी के लिए मेरी पहले SO answer और about_Arrays देखें।

1

मुझे लगता है कि यह परिस्थितियों पर निर्भर करेगा। आप केवल एक बार है कि पहला तत्व हटाने की जरूरत है, तो आप सरणी टुकड़ा करने की क्रिया का उपयोग कर सकते हैं:

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

आप इसे बार-बार ऐसा करने के लिए जा रहे हैं, तो आप एक ArrayList या सामान्य संग्रह के साथ शुरू करना चाहिए। यदि यह एक बड़ी सरणी है, तो आप केवल उस अभिव्यक्ति को रखना चाहते हैं जो इसे स्क्रिप्टब्लॉक में बना रहा है और पाइपलाइन को सरणी बनाने और उसे संग्रह में बदलने के बजाय उस पर एक .invoke() करें।

0

देर से उत्तर क्षमा करें, लेकिन मैं इसके साथ भी संघर्ष कर रहा था। मेरे इरादे और उद्देश्यों के लिए (एक पाठ फ़ाइल को लिखना), मुझे एहसास हुआ कि चूंकि सरणी एक निश्चित आकार थी - इसे हटाने के बजाय मैं केवल मूल्य को string.empty पर सेट कर सकता था।

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

मेरे लिए यह हेडर से छुटकारा पा लिया जो मैं अपनी फ्लैट फ़ाइल में नहीं चाहता था। उम्मीद है कि यह किसी और को वहां मदद करता है।

2

बस अद्यतन करने के लिए - वहाँ यह आपको एक और अधिक परिष्कृत का सहारा के बिना एक सरणी से एक मनमाना तत्व के हर घटना को दूर करने के लिए अनुमति देगा @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

में कोई समस्या है .NET ऑब्जेक्ट।

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

यह वही करेगा, लेकिन केवल तत्वों में से एक को हटा देगा। यदि डुप्लिकेट हैं, तो वे बने रहेंगे।

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

उपरोक्त, यह मेरे लिए चाल है। और यह अच्छा और संक्षिप्त है। – Spikee

+0

यदि सरणी में डुप्लिकेट मान हैं तो यह गलत तरीके से व्यवहार कर सकता है। –

+0

@RonMacNeil, अच्छा बिंदु। मैंने अपना जवाब अपडेट कर लिया है। –

संबंधित मुद्दे