gpt4 book ai didi

.net - 是否存在指定的(子)索引分隔符?

转载 作者:行者123 更新时间:2023-12-05 09:27:15 27 4
gpt4 key购买 nike

背景

在 PowerShell 中构建 hash table 是很常见的通过特定属性快速访问对象,例如以 LastName 为基础建立索引:

$List =  ConvertFrom-Csv @'
Id, LastName, FirstName, Country
1, Aerts, Ronald, Belgium
2, Berg, Ashly, Germany
3, Cook, James, England
4, Duval, Frank, France
5, Lyberg, Ash, England
6, Fischer, Adam, Germany
'@

$Index = @{}
$List |ForEach-Object { $Index[$_.LastName] = $_ }

$Index.Cook

Id LastName FirstName Country
-- -------- --------- -------
3 Cook James England

在某些情况下,需要在两个(或更多)属性上建立索引,例如FirstNameLastName。为此,您可以创建一个多维 key ,例如:

$Index = @{}
$List |ForEach-Object {
$Index[$_.FirstName] = @{}
$Index[$_.FirstName][$_.LastName] = $_
}

$Index.James.Cook

Id LastName FirstName Country
-- -------- --------- -------
3 Cook James England

但是连接这两个属性更容易(甚至可能更快)。如果仅用于检查条目是否存在:$Index.ContainsKey('James').ContainsKey('Cook') 如果 FirstName 不存在,可能会发生错误'不存在。
要连接属性,需要在属性之间使用分隔符,否则不同的属性列表可能会以相同的键结尾。如本例所示:AshlyBergAshLyberg

$Index = @{}
$List |ForEach-Object { $Index["$($_.FirstName)`t$($_.LastName)"] = $_ }

$Index."James`tCook"

Id LastName FirstName Country
-- -------- --------- -------
3 Cook James England

注:以上为Minimal, Reproducible Examples .在现实生活中,我多次遇到以下问题,其中包括通常在背景和索引中使用的属性数量可变的情况下连接对象。

问题:

  1. 在这种情况下加入(串联)属性是一种好的做法吗?
  2. 如果是,是否有(标准?)分隔符? (意思是一个字符 - 或一系列字符 - 不应在属性名称中使用/存在)

最佳答案

编辑:虽然以下解决方案有效,但它远不如 solution provided by mklement0 干净,我推荐使用。元组在许多其他情况下也很有用,所以我将以这个答案为例。


我建议在 Tuple 的帮助下使用“拆分键”而不是连接键类(class)。在这种情况下,不需要分隔符,因为键没有连接,而是作为单独的属性存储在对象中。 Tuple 类提供了必要的接口(interface),因此当在任何 Dictionary(例如 Hashtable)中使用时,元组就像一个键一样。

$List =  ConvertFrom-Csv @'
Id, LastName, FirstName, Country
1, Aerts, Ronald, Belgium
2, Berg, Ashly, Germany
3, Cook, James, England
4, Duval, Frank, France
5, Lyberg, Ash, England
6, Fischer, Adam, Germany
'@

$Index = @{}
$List.ForEach{ $Index[ [Tuple]::Create( $_.LastName, $_.FirstName ) ] = $_ }

$Index

当写入控制台时,拆分键的格式很好:

Name                           Value
---- -----
(Berg, Ashly) @{Id=2; LastName=Berg; FirstName=Ashly; Country=Germany}
(Lyberg, Ash) @{Id=5; LastName=Lyberg; FirstName=Ash; Country=England}
(Duval, Frank) @{Id=4; LastName=Duval; FirstName=Frank; Country=France}
(Aerts, Ronald) @{Id=1; LastName=Aerts; FirstName=Ronald; Country=Belgium}
(Cook, James) @{Id=3; LastName=Cook; FirstName=James; Country=England}
(Fischer, Adam) @{Id=6; LastName=Fischer; FirstName=Adam; Country=Germany}

要查找一个条目,创建一个临时元组:

$Index[ [Tuple]::Create('Duval','Frank') ]

Tuple 类的一个优点是您可以轻松获取构成拆分键的各个键,而无需拆分字符串:

# Using member access enumeration
$Index.Keys.Item1 # Prints all last names
$Index.Keys.Item2 # Prints all first names

# Using the enumerator to loop over the index
$Index.GetEnumerator().ForEach{ $_.Key.Item1 }

.NET Framework 4.7 添加了 ValueTuple 结构 ( what's the difference? )。可能值得测试它是否为此用例提供更好的性能。此外,用通用的 Dictionary 替换 Hashtable 也可以提高性能:

$Index = [Collections.Generic.Dictionary[ ValueTuple[String,String], object]]::new()

除了构建字典,ValueTuple 还可以像Tuple 一样使用。只需将前面的代码示例中的 Tuple 替换为 ValueTuple

关于.net - 是否存在指定的(子)索引分隔符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72772327/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com