当前位置: 首页 > 知识库问答 >
问题:

如何将哈希表枚举为键值对/通过键值集合过滤哈希表

丁宏盛
2023-03-14

编者按:这个问题有一个复杂的历史,但归结为:
*要了解如何通过键值对枚举哈希表的条目,请参阅接受的答案。
*要了解如何通过键值的集合,请参阅其他答案。

我想我又陷入了XY问题,我最初的问题是关于过滤哈希表。我发现在创建哈希表之前更容易过滤。问题回答了,对吧?

不,Y问题是循环每个键并使用@briantist帮助我的值。

我的目标是循环使用键名(即时间戳),并使用键名作为任务名称和触发器来安排任务。

我正在使用Group-Object-AsHashTable-AsString-edit从CSV文件创建一个哈希表,这里值得一提的是,在创建哈希表之前过滤CSV只会让Pipeline或脚本更容易。

作为一个例子:

Import-CSV (ls -path D:\ -Filter source*.csv | sort LastWriteTime | Select -Last 1).FullName |
 where {$_.TimeCorrected -ne 'ManualRebootServer'} |
 group TimeCorrected -AsHashTable -AsString

我试图循环在关键名称,并能够显示关键名称使用:

$var = Import-Csv csv123.csv | Group-Object Value1 -AsHashTable -AsString

foreach ($key in $var.Keys){"The key name is $key"}

#Create a scheduled task named and triggered based on the HashTable keyname
#test test test
foreach ($key in $var.keys){IF($key -ne 'ManualRebootServer'){"Register-ScheduledJob"}}

我只是不知道如何从我感兴趣的键中获取值。

我发现以下方法有效,但只有在手动输入密钥名时才有效。我只是不知道如何组合这两个循环。

($val.GetEnumerator() | Where {$_.key -eq '06-11-16 18:00'} | ForEach-Object { $_.value }).Server

共有2个答案

齐运诚
2023-03-14

为了补充briantist的有用答案,我们将重点放在通过键值数组(PSv3语法)过滤哈希表上:

# Sample hashtable.
$ht = @{ one = 1; two = 2; three = 3 }

# Filter it by an array of key values; applying .GetEnumerator() yields an array
# of [System.Collections.DictionaryEntry] instances, which have
# a .Key property and a .Value property.
$ht.GetEnumerator()  | ? Key -in 'one', 'two'

# Similarly, the *output* - even though it *looks* like a hashtable - 
# is a regular PS *array* ([Object[]]) containing [System.Collections.DictionaryEntry]
# entries (2 in this case).
$arrFilteredEntries = $ht.GetEnumerator()  | ? Key -in 'one', 'two'
$arrFilteredEntries.GetType().Name # -> Object[]

要进一步处理匹配的键值对,只需通过管道连接到%ForEach Object)并访问$。按和$键。值(值):

$ht.GetEnumerator()  | ? Key -in 'one', 'two' | 
  % { "Value for key '$($_.Key)': $($_.Value)" }

使用更高效的foreach循环而不是管道的等效命令:

foreach ($key in $ht.Keys) { 
  if ($key -in 'one', 'two') { "Value for key '$($key)': $($ht.$key)" }
}

注意:在PSv2中:
*运算符-In不受支持,但可以使用-contains替换操作数:
'one',two'-contains$key
*在管道中,使用其中对象{'one',two'-contains$.key}

对于示例哈希表,这将产生:

Value for key 'two': 2
Value for key 'one': 1

注意输出中的键顺序如何不同于定义顺序;在PSv3中,您可以创建有序的哈希表([有序]@{...})来保留定义顺序。

上面使用的密钥过滤技术不限于通过文本密钥数组进行过滤;任何(字符串)集合都将作为操作数中-in的RHS,例如。键不同哈希表的集合:

# Sample input hashtable.
$htInput = @{ one = 1; two = 2; three = 3 }

# Hashtable by whose keys the input hashtable should be filtered.
# Note that the entries' *values* are irrelevant here.
$htFilterKeys = @{ one = $null; two = $null }

# Perform filtering.
$htInput.GetEnumerator()  | ? Key -in $htFilterKeys.Keys | 
  % { "Value for key '$($_.Key)': $($_.Value)" }

# `foreach` loop equivalent:
foreach ($key in $htInput.Keys) {
  if ($key -in $htFilterKeys.Keys) { "Value for key '$($key)': $($htInput.$key)" }
}

结果与静态过滤器键数组的示例中相同。

最后,如果您想过滤一个哈希表,或者创建一个只包含筛选条目的新哈希表:

# *In-place* Updating of the hashtable.
# Remove entries other than the ones matching the specified keys.
# Note: The @(...) around $ht.Keys is needed to clone the keys collection before
# enumeration, so that you don't get an error about modifying a collection
# while it is being enumerated.
foreach ($key in @($ht.Keys)) { 
  if ($key -notin 'one', 'two') { $ht.Remove($key) } 
} 

# Create a *new* hashtable with only the filtered entries.
# By accessing the original's .Keys collection, the need for @(...) is obviated.
$htNew = $ht.Clone()
foreach ($key in $ht.Keys) { 
  if ($key -notin 'one', 'two') { $htNew.Remove($key) }
} 

作为旁白:

[System.Collections.DictionaryEntry](因此哈希表([System.Collections.Hashtable])的默认输出格式使用列名名称,而不是Name定义为PowerShell添加的Key的别名属性(它不是[System.Collections.DictionaryEntry].NET类型定义的一部分;请使用
@{one=1}.GetEnumerator()| Get Member进行验证)。

仲孙文乐
2023-03-14

你有一些选择。

通过键枚举:

foreach ($key in $var.Keys) {
    $value = $var[$key]
    # or
    $value = $var.$key 
}

枚举键值对(您已经发现,但可能无法有效使用):

foreach ($kvp in $var.GetEnumerator()) {
    $key = $kvp.Key
    $val = $kvp.Value
}
 类似资料:
  • 我在Java有以下问题。 我有一个eunm,它包含两个值,代表两个字符串值“协调”和“PISC”: 因此,我创建了这个getEnums()方法,它返回一个哈希集,其中包含作为字符串的枚举值: 问题是,当这个方法被称为返回值对象包含2字符串,我认为,但使用deubugget的值放入这个HashSet不是协调和PISC,而是这样的东西: 我认为问题与如何将值插入值哈希集中有关 然后,在代码的其他地方,

  • 我想在命令行上这样做,所以像这样的事情会很好: 上面的方法当然不适合散列。所以最后我需要打电话 以自动化的方式。

  • 我在Spring和Redis上都很新。我想知道有没有办法按价值得到钥匙? 例如,我希望获得具有给定文件哈希和内容的图像类型文件的get the KEY。我是这样做的: 然而,我被告知这是相当昂贵的,因为我要获得所有以“image”开头的键,并手动检查所有这些键。 现在我在想,也许如果我能按价值得到钥匙会好得多。以便更容易得到它的所有属性。在Redis可能吗?

  • 输入是一个哈希映射,比如 我想写一个方法,返回类型A的列表,其中有键,值属性与字符串类型,和键值从hashmap。 如何让它成为现实?

  • 当人们说Hashmap比列表更快时,我对Hashmap或Hashtable的概念更困惑。我很清楚散列的概念,其中的值存储在给定密钥的散列代码中。 但是,当我想检索数据时,例如,它是如何工作的,我在一个HashMap中存储n个带有n个不同键的字符串。如果我想检索与特定键关联的特定值,它将如何在O(1)的时间内返回它?因为散列密钥将与所有其他密钥进行比较,对吗?