从哈希表中删除重复值
Remove duplicate values from hashtables
我是 powershell 的新手,我需要从哈希表中删除重复值,例如 "c"
有重复的 3 - "3,4,3"
和 "d"
有重复的 1 - "1,1,6,4"
.
[hashtable]$alpha = @{
"a" = "1";
"b" = "2,1,5";
"c" = "3,4,3";
"d" = "1,1,6,4";
"e" = "1,7,9,0";
}
我怎样才能得到结果?
我已经试过了select-object -unique
但是没用。
为了使用Select-Object -Unique
,您的值必须在集合(数组)中,而不是在单个字符串.
因此,您必须首先将字符串拆分为一个标记数组(-split
运算符),然后将不同的标记重新组合成一个字符串(-join
运算符)。
foreach ($key in @($alpha.Keys)) {
$alpha.$key = ($alpha.$key -split ',' | Select-Object -Unique) -join ','
}
请注意 $alpha.Keys
周围的 @(...)
,它有效地 克隆了 密钥集合,这是必要的,否则您会因尝试而出错不支持在枚举时修改集合。
在 PSv3+ 中,您可以使用 $alpha.Keys.Clone()
代替,这样效率更高。
您还可以使用 管道 调用 ForEach-Object
(%
) cmdlet (而不是 表达式 和 foreach
循环 ),但是 对于内存数据结构 foreach
loop 通常是更好更快的选择.
为了完整起见,这里是管道解决方案( 提炼它的提示):
@($alpha.Keys) | ForEach-Object {
$alpha[$_] = ($alpha[$_.] -split ',' | Select-Object -Unique) -join ','
}
注意在$alpha.Keys
附近仍然需要@(...)
,如foreach
语句解决方案。
与 foreach
解决方案一样,这会修改哈希表。
另一种选择是使用 $alpha.GetEnumerator()
以强制 PowerShell 通过管道,作为 [System.Collections.DictionaryEntry]
实例,表示具有 .Key
和 .Value
属性 的键值对 - 默认情况下,PowerShell 输出哈希表 作为一个整体 。
但是,需要创建一个新的哈希表,因为您根本无法修改使用[枚举的集合=31=](也被 foreach
循环隐式使用).
$newAlpha = @{} # initialize the new hash table
$alpha.GetEnumerator() | ForEach-Object {
$newAlpha[$_.Key] = ($alpha[$_.Key] -split ',' | Select-Object -Unique) -join ','
}
# $newAlpha now contains the updated entries.
如前所述,这些是字符串,先拆分它们,然后重新加入:
$NewAlpha = $Alpha.GetEnumerator() |% { $_.value = ($_.value -split "," | select -unique) -join "," ; $_}
注意:这不会保留 [hashtable] 类型。
为此,您需要采用 mklement0
提供的答案中提到的方法
@($alpha.Keys) |% {$alpha.$_ = ($alpha.$_ -split ',' | Select-Object -Unique) -join ','}
我是 powershell 的新手,我需要从哈希表中删除重复值,例如 "c"
有重复的 3 - "3,4,3"
和 "d"
有重复的 1 - "1,1,6,4"
.
[hashtable]$alpha = @{
"a" = "1";
"b" = "2,1,5";
"c" = "3,4,3";
"d" = "1,1,6,4";
"e" = "1,7,9,0";
}
我怎样才能得到结果?
我已经试过了select-object -unique
但是没用。
为了使用Select-Object -Unique
,您的值必须在集合(数组)中,而不是在单个字符串.
因此,您必须首先将字符串拆分为一个标记数组(-split
运算符),然后将不同的标记重新组合成一个字符串(-join
运算符)。
foreach ($key in @($alpha.Keys)) {
$alpha.$key = ($alpha.$key -split ',' | Select-Object -Unique) -join ','
}
请注意 $alpha.Keys
周围的 @(...)
,它有效地 克隆了 密钥集合,这是必要的,否则您会因尝试而出错不支持在枚举时修改集合。
在 PSv3+ 中,您可以使用 $alpha.Keys.Clone()
代替,这样效率更高。
您还可以使用 管道 调用 ForEach-Object
(%
) cmdlet (而不是 表达式 和 foreach
循环 ),但是 对于内存数据结构 foreach
loop 通常是更好更快的选择.
为了完整起见,这里是管道解决方案(
@($alpha.Keys) | ForEach-Object {
$alpha[$_] = ($alpha[$_.] -split ',' | Select-Object -Unique) -join ','
}
注意在$alpha.Keys
附近仍然需要@(...)
,如foreach
语句解决方案。
与 foreach
解决方案一样,这会修改哈希表。
另一种选择是使用 $alpha.GetEnumerator()
以强制 PowerShell 通过管道,作为 [System.Collections.DictionaryEntry]
实例,表示具有 .Key
和 .Value
属性 的键值对 - 默认情况下,PowerShell 输出哈希表 作为一个整体 。
但是,需要创建一个新的哈希表,因为您根本无法修改使用[枚举的集合=31=](也被 foreach
循环隐式使用).
$newAlpha = @{} # initialize the new hash table
$alpha.GetEnumerator() | ForEach-Object {
$newAlpha[$_.Key] = ($alpha[$_.Key] -split ',' | Select-Object -Unique) -join ','
}
# $newAlpha now contains the updated entries.
如前所述,这些是字符串,先拆分它们,然后重新加入:
$NewAlpha = $Alpha.GetEnumerator() |% { $_.value = ($_.value -split "," | select -unique) -join "," ; $_}
注意:这不会保留 [hashtable] 类型。 为此,您需要采用 mklement0
提供的答案中提到的方法@($alpha.Keys) |% {$alpha.$_ = ($alpha.$_ -split ',' | Select-Object -Unique) -join ','}