2011-05-04 17 views
29

Ben karma tablo döngü çalışıyor ve 5'e her anahtarı değerini ve Powershell hata veriyor ediyorum:Powershell bir foreach döngüsünde hash tablosu değerlerini güncelleştirme?

Collection was modified; enumeration operation may not execute.. 
At line:1 char:8 
+ foreach <<<< ($key in $myHash.keys){ 
    + CategoryInfo   : InvalidOperation: (System.Collecti...tableEnumer 
    ator:HashtableEnumerator) [], RuntimeException 
    + FullyQualifiedErrorId : BadEnumeration 

: Bir topluluk içinde numaralandırılırken bir hata oluştu

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

foreach($key in $myHash.keys){ 
    $myHash[$key] = 5 
} 

Ne verir ve nasıl çözerim?

+0

İlgili soru: http: // stackoverflow.com/questions/4726137/collection-değiştirilmiş-numaralandırma-işlemi-değil-yürütme-ne zaman-güncelleme-değeri – tenpn

cevap

40

Numaralandırılırken, Hashtable değiştiremezsiniz. Bu ne yapabildiğini geçerli:

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

$myHash = $myHash.keys | foreach{[email protected]{}}{$r[$_] = 5}{$r} 

düzenleme 1

sizin için bu herhangi bir basit mi:

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

foreach($key in $($myHash.keys)){ 
    $myHash[$key] = 5 
} 
+1

Teşekkürler zespri ---- bu düz bir operasyon olması gereken için acımasız acı .... – ted

+0

Powershell çok esnektir. Aynı şeyi başarmanın birçok yolu vardır. Kuşkusuz, öğrenmek zaman alır, ama bir kez orada bu tür şeyler kolay gelir. Cevabımı sizin için daha sezgisel görünebilecek bir yol sağlamak için düzenledim. Bu, orijinal olarak koyduğunuz biçime daha çok benziyor. –

+0

@ted: rica ederim. Yanıtı size tatmin ederse kabul etmek isteyebilirsiniz. –

0

Eğer foreach içindeki karma tablosunu güncelleştirmek, listeleyicisi geçersiz kılmaktadır görünüyor kendisi.

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

$newHash = @{} 
foreach($key in $myHash.keys){ 
    $newHash[$key] = 5 
} 
$myHash = $newHash 
+0

iyi bir fikir, ama büyük sözlükler için çok yavaş olurdu ... –

3

kullanın clone: Yeni bir karma tablo yerleştirmenin bu sorunu var

 
$myHash = ($myHash.clone()).keys | % {} {$myHash[$_] = 5} {$myHash} 
+1

Birisi neden yakın zamanda -2 aldığımı açıklayabilir mi? Bu yardımcı olur. –

+0

bu çalışır. Teşekkürler. –

+0

değerini (daha sonraki sürümler için Powershell v2 bilmemek) değiştirmeden önce neden yüklenme gereksiniminin klonlanabileceğini açıklayabilir misiniz? –

10

ulaşma çok daha basit bir yolu var:

 
foreach($key in ($myHash.clone()).keys){ 
    $myHash[$key] = 5 
} 

veya bir poşetine

bu. Bir referans tipi değişkeni olduğu için, bir sığınağın değerini değiştirirken, onu sıralayamazsınız. Tam olarak aynı hikaye. Net.

Etrafında gezinmek için aşağıdaki sözdizimini kullanın. Burada yaptığımız şey, anahtar koleksiyonunu @() notasyonu kullanarak temel bir diziye dönüştürmektir. Anahtar koleksiyonunun bir kopyasını yapıyoruz ve bunun yerine diziyi referans alıyoruz, yani şimdi hashtable'ı düzenleyebiliyoruz.

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

foreach($key in @($myHash.keys)){ 
    $myHash[$key] = 5 
} 
+0

Re: 'Tam olarak aynı şey. Net.'de ... Powershell IS .NET. Sadece söylüyorum. – Cheeso

+0

@() operatörünü neden kullandığınızı açıkladığınız için teşekkür ederiz. Başka bir cevapta görünüyor ama neler olduğunu açıklamıyorlardı. –

2

Ben PowerShell yeniyim, ama daha okunabilir bulmak, çünkü dahili işlevleri kullanarak oldukça hayranıyım. GetEnumerator ve Clone kullanarak bu sorunu nasıl çözeceğim. Bu yaklaşım ayrıca, değişiklik yapma amacıyla mevcut karma değerlerine ($ _. Value) başvurulmasına da izin verir.

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

$myHash.Clone().GetEnumerator() | foreach-object {$myHash.Set_Item($_.key, 5)} 
2

Yaratıcı olmak zorundasınız!

$myHash = @{} 
$myHash["a"] = 1 
$myHash["b"] = 2 
$myHash["c"] = 3 

$keys = @() 
[array] $keys = $myHash.keys 

foreach($key in $keys) 
    { 
    $myHash.Set_Item($key, 5) 
    } 

$myHash 

Name       Value                                                 
----       -----                                                 
c        5                                                  
a        5                                                  
b        5  
+1

OP komut dosyasının neden çalışmadığını açıklayan yanıtı geliştirebilirsiniz. – mnencia

0

Yukarıda belirtildiği gibi, klon gitmek için bir yoldur. "Bilinmeyen" ile bir hash içindeki herhangi bir null değerin değiştirilmesi gerekiyordu ve bu tek liner işi yapıyor.

($ record.Clone()). % {if ($ record. $ _ -eq $ null) {$ record. $ _ = "Bilinmeyen"}}

3

Sadece zorlayıcı tarafından anahtar koleksiyonunu numaralandırıyorsanız, bu örnek için tüm hashtable'ı kopyalamanız gerekmez. Bir dizi için @(...) yeterlidir:

foreach($key in @($myHash.keys)){...
İlgili konular