提问人:Jay_C_NNJ 提问时间:11/10/2023 最后编辑:Jay_C_NNJ 更新时间:11/11/2023 访问量:41
Powershell - 在数组中搜索是否存在哈希表中的值
Powershell - Search an array for presence of value from a hash table
问:
我正在将标题行从 Excel 电子表格加载到数组中,并需要将其与每个值具有多个键条目的哈希表进行比较。我需要能够为我正在搜索的每个列提供不同的变体。 数组包含标题行 (人名、Customer_Account_Number、电力公司、公司名称、Service_Address_1、Service_City、Service_State、Service_Zip、电话号码)
我需要像这样设置我的变量:
$nameColumn = 1 $companyColumn = 4
$headers = @()
for ($col = 1; $col -le $worksheet.UsedRange.Columns.Count; $col++) {
$headers += $($worksheet.Cells.Item(1, $col).Text)
}
$headerMappings = @{
"name" = "Name";
"person name" = "Name";
"contact Name" = "Name"
"company name" = "Company"
"service_address_1" = "Address"
"address" = "Address"
"service_city" = "City"
"city" = "City"
"service_state" = "State"
"state" = "State"
"service_zip" = "Zip"
"zip" = "Zip"
"phone number" = "Phone"
"phone" = "Phone"
}
# Get column indices for specific field names using headerMappings
$nameColumn = $headers.IndexOf($headerMappings["Name"])
$companyColumn = $headers.IndexOf($headerMappings["Company"])
$addressColumn = $headers.IndexOf($headerMappings["Address"])
$cityColumn = $headers.IndexOf($headerMappings["City"])
$stateColumn = $headers.IndexOf($headerMappings["State"])
$zipColumn = $headers.IndexOf($headerMappings["Zip"])
$phoneColumn = $headers.IndexOf($headerMappings["Phone"])
答:
$headers
是一个数组,是一个哈希表。$headerMappings
我建议采用两步法:
创建一个映射标头名称数组,用于翻译;例如,翻译为 .
$headerMappings
service_address_1
Address
然后,根据映射的标头名称数组进行查找。
.IndexOf()
# Sample input array.
$headers = 'person name', 'service_state', 'phone', 'service_address_1'
$headerMappings = @{
"name" = "Name"
"person name" = "Name"
"contact Name" = "Name"
"company name" = "Company"
"service_address_1" = "Address"
"address" = "Address"
"service_city" = "City"
"city" = "City"
"service_state" = "State"
"state" = "State"
"service_zip" = "Zip"
"zip" = "Zip"
"phone number" = "Phone"
"phone" = "Phone"
}
# Translate the headers to their mapped names.
# Note: This assumes that all headers names are covered by the hashtable.
$mappedHeaders = @($headers | ForEach-Object { $headerMappings[$_] })
# Get column indices based on the array of *mapped* header names.
# Note: .IndexOf() is *case-sensitive*.
# ...
$addressColumn = $mappedHeaders.IndexOf('Address') # -> 3
请注意,如果给定的标头数组包含多个映射到哈希表中相同名称的标头,则上述将仅报告第一个此类标头的索引。
至于你试过的:
$headerMappings["Name"]
"Name"
是哈希表条目值,而不是键;它被用于多个条目中,即带有键 、 和 的条目。"name"
"person_name"
"contact_Name"
因此,表达式的计算结果可预测为 ,并且调用可预测地返回(以指示输入对象不是数组的一部分)。$null
.IndexOf()
-1
如果你想在没有中间帮助程序数组的情况下执行此操作(如上所示),则必须执行以下操作,但是,这是低效的,因为它涉及在整个数组中搜索每个索引:
$headers.IndexOf(
$headers.Where({ $headerMappings[$_] -eq 'Address' }, 'First')[0]
)
另一个答案建立在您自己的方法之上,即将列(标题)索引存储在不同的变量中。
另一种方法是构建另一个哈希表,将映射的标题映射到列索引。
$headerIndexMappings = @{}
$i = 0
$headers | ForEach-Object {
$headerIndexMappings[$headerMappings[$_]] = $i++
}
然后,您可以使用映射的标头名称访问生成的哈希表,以检索原始标头的索引;例如,或者 - 更简单地说 - 另一个答案中样本数组的产量。$headerIndexMappings['Address']
$headerIndexMappings.Address
3
$headers
除了不需要为每个映射标头定义单独的变量之外,这种方法的优点是查找不区分大小写(就像 PowerShell 的哈希表通常一样),因此也可以使用。$headerIndexMappings.address
评论
$headers
contact Name
name