对哈希表进行排序并放入一个新的哈希表中
Sort hashtable and put into a new hashtable
我不明白为什么下面的循环是 return 个空键。
我认为 $hashSorted 不是 Hashtable 类型;那我怎么强迫它呢?
现在想想我需要一个 deep/copy 吗?我只想对我的哈希表进行排序并将其放入另一个哈希表中。
这可能是以下内容的复制品:Sort Hashtable and assign it to a new variable in Powershell
我最初的问题是为什么在执行循环时键为空。
然后我意识到它可能不是哈希表。仍在尝试那里的答案。
参考:
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=
尝试 运行 在新的清晰的 powershell 上下文中。我建议你的环境有一些变量保存在缓存中。
我看到的唯一错误是在第二个循环中。您在循环内使用 $hashSorted
而不是 $item
。应该是:
$key = $item.Key
....
$fileSize = $item.Value
编辑: 顺便说一句,使用 GetEnumerator() 排序效果很好。
编辑 2: $hashSorted.Keys
为空,因为 $hashSorted
不是哈希表,只是键值对的集合。
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 "
#}
}
这个
$hashSorted = $hashFilesAndSizes.GetEnumerator() | sort value
不会生成新的哈希表。相反,它会生成一个 DictionaryEntry
对象数组。现在,由于 $hashSorted
实际上不是哈希表,因此没有 Keys
属性 并且按值索引将不起作用。要正确构建一个保留键顺序的新哈希表,您必须这样做
$hashSorted = [ordered] @{}
$hashFilesAndSizes.GetEnumerator() | sort value | foreach {$hashSorted[$_.Key] = $_.Value}
我不明白为什么下面的循环是 return 个空键。 我认为 $hashSorted 不是 Hashtable 类型;那我怎么强迫它呢? 现在想想我需要一个 deep/copy 吗?我只想对我的哈希表进行排序并将其放入另一个哈希表中。
这可能是以下内容的复制品:Sort Hashtable and assign it to a new variable in Powershell 我最初的问题是为什么在执行循环时键为空。 然后我意识到它可能不是哈希表。仍在尝试那里的答案。
参考:
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=
尝试 运行 在新的清晰的 powershell 上下文中。我建议你的环境有一些变量保存在缓存中。
我看到的唯一错误是在第二个循环中。您在循环内使用 $hashSorted
而不是 $item
。应该是:
$key = $item.Key
....
$fileSize = $item.Value
编辑: 顺便说一句,使用 GetEnumerator() 排序效果很好。
编辑 2: $hashSorted.Keys
为空,因为 $hashSorted
不是哈希表,只是键值对的集合。
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 "
#}
}
这个
$hashSorted = $hashFilesAndSizes.GetEnumerator() | sort value
不会生成新的哈希表。相反,它会生成一个 DictionaryEntry
对象数组。现在,由于 $hashSorted
实际上不是哈希表,因此没有 Keys
属性 并且按值索引将不起作用。要正确构建一个保留键顺序的新哈希表,您必须这样做
$hashSorted = [ordered] @{}
$hashFilesAndSizes.GetEnumerator() | sort value | foreach {$hashSorted[$_.Key] = $_.Value}