代码之家  ›  专栏  ›  技术社区  ›  NealWalters

排序哈希表并放入新的哈希表

  •  0
  • NealWalters  · 技术社区  · 6 年前

    我不明白为什么下面的循环返回空键。 我认为$hashsorted不是hashtable类型;那么如何强制它是hashtable类型? 想现在我需要一个深度/副本?我只想对我的哈希表进行排序并将其放入另一个哈希表中。

    这可能是重复的: Sort Hashtable and assign it to a new variable in Powershell 我最初的问题是为什么在循环时键是空的。 然后我意识到它可能不是一个哈希表。还在尝试答案。

    参考文献: How can I enumerate a hashtable as key-value pairs / filter a hashtable by a collection of key values

    cls
    $hashFilesAndSizes = @{}
    $hashSorted = @{}
    $hashFilesAndSizes.Add("file1.txt",1000)
    $hashFilesAndSizes.Add("file2.txt",200)
    $hashFilesAndSizes.Add("file3.txt",750)
    $hashFilesAndSizes.GetEnumerator() | sort value  #Displays sorted hash table 
    
    Write-Host "Second Try - put in another hashtable"
    $hashSorted = $hashFilesAndSizes.GetEnumerator() | sort value  #put into a new variable 
    Write-Host "Original variable in original Order" 
    $hashFilesAndSizes
    Write-Host "Sorted" 
    $hashSorted #show results 
    
    Write-Host "Why loop has null keys?"
    
      foreach($key in $hashSorted.Keys) 
       {
          Write-Host "Key=$key" 
          #if (-not ([string]::IsNullOrEmpty($key)))
          #{
              $keyPadded = $key.PadRight(50," ")
              $fileSize = $hashSorted[$key] 
              $fileSizeFormatted = $fileSize.ToString("000,000")
              Write-Host "$keyPadded  size=$fileSizeFormatted "
          #}
       }
    
    Write-Host "Test with enumerator"
    
      foreach($item in $hashSorted.GetEnumerator()) 
       {
          $key = $hashSorted.Key 
          Write-Host "Key=$key" 
          #if (-not ([string]::IsNullOrEmpty($key)))
          #{
              $keyPadded = $key.PadRight(50," ")
              $fileSize = $hashSorted.Value
              $fileSizeFormatted = $fileSize.ToString("000,000")
              Write-Host "$keyPadded  size=$fileSizeFormatted "
          #}
       }
    

    结果

    > Name                           Value                                  
    > 
    > ----                           -----                                                                                                                     file2.txt                      200                                    
    > file3.txt                      750                                    
    > file1.txt                      1000                                   
    > Second Try - put in another hashtable Original variable in original
    > Order file3.txt                      750                              
    > file1.txt                      1000                                   
    > file2.txt                      200                                    
    > Sorted file2.txt                      200                             
    > file3.txt                      750                                    
    > file1.txt                      1000                                   
    > Why loop has null keys? Key= You cannot call a method on a null-valued
    > expression. At C:\Scripts\HashTableSortTest.ps1:23 char:37
    > +           $keyPadded = $key.PadRight <<<< (50," ")
    >     + CategoryInfo          : InvalidOperation: (PadRight:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull   Index operation failed; the array index evaluated to null. At
    > C:\Scripts\HashTableSortTest.ps1:24 char:35
    > +           $fileSize = $hashSorted[ <<<< $key] 
    >     + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    >     + FullyQualifiedErrorId : NullArrayIndex   You cannot call a method on a null-valued expression. At
    > C:\Scripts\HashTableSortTest.ps1:25 char:50
    > +           $fileSizeFormatted = $fileSize.ToString <<<< ("000,000")
    >     + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull
    >     size=  
    >Test with enumerator Key= You cannot call a method on a null-valued expression. At C:\Scripts\HashTableSortTest.ps1:38 char:37
    > +           $keyPadded = $key.PadRight <<<< (50," ")
    >     + CategoryInfo          : InvalidOperation: (PadRight:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull   You cannot call a method on a null-valued expression. At
    > C:\Scripts\HashTableSortTest.ps1:40 char:50
    > +           $fileSizeFormatted = $fileSize.ToString <<<< ("000,000")
    >     + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull
    >     size=  Key= You cannot call a method on a null-valued expression. At C:\Scripts\HashTableSortTest.ps1:38 char:37
    > +           $keyPadded = $key.PadRight <<<< (50," ")
    >     + CategoryInfo          : InvalidOperation: (PadRight:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull   You cannot call a method on a null-valued expression. At
    > C:\Scripts\HashTableSortTest.ps1:40 char:50
    > +           $fileSizeFormatted = $fileSize.ToString <<<< ("000,000")
    >     + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull
    >     size=  Key= You cannot call a method on a null-valued expression. At C:\Scripts\HashTableSortTest.ps1:38 char:37
    > +           $keyPadded = $key.PadRight <<<< (50," ")
    >     + CategoryInfo          : InvalidOperation: (PadRight:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull   You cannot call a method on a null-valued expression. At
    > C:\Scripts\HashTableSortTest.ps1:40 char:50
    > +           $fileSizeFormatted = $fileSize.ToString <<<< ("000,000")
    >     + CategoryInfo          : InvalidOperation: (ToString:String) [], RuntimeException
    >     + FullyQualifiedErrorId : InvokeMethodOnNull
    >     size=
    
    3 回复  |  直到 6 年前
        1
  •  3
  •   Bruce Payette    6 年前

    这个

    $hashSorted = $hashFilesAndSizes.GetEnumerator() | sort value 
    

    生成新的哈希表。相反,它产生一个数组 DictionaryEntry 物体。现在以来 $hashSorted 实际上,不是哈希表 Keys 属性和按值索引将不起作用。要正确地构造一个新的哈希表,它保留了您必须执行的键顺序

    $hashSorted = [ordered] @{}
    $hashFilesAndSizes.GetEnumerator() | sort value | foreach {$hashSorted[$_.Key] = $_.Value}
    
        2
  •  1
  •   Mikhail Tumashenko    6 年前

    尝试运行在新的清晰的电源外壳上下文中。我建议您的环境在缓存中保存一些变量。

    我看到的唯一错误是在第二个循环中。你在用 $hashSorted 在循环中而不是 $item . 应该是:

      $key = $item.Key 
      ....
      $fileSize = $item.Value
    

    编辑: 顺便说一下,使用getEnumerator()进行排序工作得很好。

    编辑2: $hashSorted.Keys 是空的 美元散列 不是哈希表,只是键值对的集合。

        3
  •  0
  •   iRon    6 年前
    Write-Host "Test with enumerator"
    
      foreach($item in $hashSorted.GetEnumerator()) 
       {
          $key = $item.Key                                        # Not $hashSorted.Key !
          Write-Host "Key=$key" 
          #if (-not ([string]::IsNullOrEmpty($key)))
          #{
              $keyPadded = $key.PadRight(50," ")
              $fileSize = $item.Value                             # Not $hashSorted.Value !
              $fileSizeFormatted = $fileSize.ToString("000,000")
              Write-Host "$keyPadded  size=$fileSizeFormatted "
          #}
       }