Tuples/ArrayList 对
Tuples/ArrayList of pairs
我实际上是在尝试创建一个配对列表,事实证明这非常困难
在有人提到 Hashtables 之前请注意,会有我不关心的重复项。
例如,如果我这样做
$b = @{"dog" = "cat"}
我明白了
名称值
---- -----
狗猫
哪个好。但是,我无法添加
之类的内容
$b += @{"dog" = "horse"}
Item has already been added. Key in dictionary: 'dog' Key being added: 'dog'
我只是想创建一个 table 数据 ,我可以使用 .Add()
或 +=
之类的东西将其添加到 。
我相信哈希表列表应该可以完成您所追求的。
$ht = @{foo='bar'}
$list = [System.Collections.Generic.List[hashtable]]::new()
$list.Add($ht)
$list.Add($ht)
$list.Add($ht)
$list
提供了一种有效且高效的解决方案 - 尽管有点晦涩难懂。
创建哈希表的 数组 是最简单的解决方案,但重要的是要注意 "extending" 数组意味着隐式地 重新创建 它,鉴于数组是固定大小的数据结构,这可能会成为多次迭代的性能问题:
# Using array-construction operator ",", create a single-element array
# containing a hashtable
$b = , @{ dog = "cat"}
# "Extend" array $b by appending another hashtable.
# Technically, a new array must be allocated that contains the original array's
# elements plus the newly added one.
$b += @{ dog = "horse"}
This GitHub issue 讨论了未来可能的增强功能,使 PowerShell 本机支持可有效扩展的类似列表的数据类型,或者甚至 default 这种数据类型。 (从 Windows PowerShell v5.1 / PowerShell Core 6.2.0 开始,PowerShell 默认为 [object[]]
类型的固定大小数组)。
如果你想要一个元组列表,我建议实际构建一个 tuples:
的列表
$list = @()
$tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat'
$tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse'
$list += $tuple1
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
$list += $tuple2
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
# dog horse 2
请注意,在这个例子中 $list
是一个常规数组,这意味着,正如 在他的回答中指出的那样,用 +=
赋值运算符附加到它会重新创建大小增加 1 的数组,将新项放入新的空槽中,然后替换原来的数组。对于少量追加操作,这通常不是大问题,但随着追加操作数量的增加,性能影响变得显着。
使用 ArrayList
而不是普通数组可以避免此问题:
$list = New-Object Collections.ArrayList
$tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat'
$tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse'
$list.Add($tuple1) | Out-Null
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
$list.Add($tuple2) | Out-Null
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
# dog horse 2
ArrayList
对象的 Add()
方法输出附加项目的索引。 Out-Null
抑制在大多数情况下不需要的输出。如果您想使用这些索引号,您可以将它们收集到一个变量中而不是丢弃它们 ($i = $list.Add($t1)
)。
如果你想避免一直指定新元组的类型,你可以将它包装成一个可重用的函数,如下所示:
function New-Tuple {
Param(
[Parameter(Mandatory=$true)]
[ValidateCount(2,2)]
[string[]]$Values
)
New-Object 'Tuple[String,String]' $Values
}
$tuple1 = New-Tuple 'dog', 'cat'
$tuple2 = New-Tuple 'dog', 'horse'
或者,以更通用的方式,像这样:
function New-Tuple {
Param(
[Parameter(
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[ValidateCount(2,20)]
[array]$Values
)
Process {
$types = ($Values | ForEach-Object { $_.GetType().Name }) -join ','
New-Object "Tuple[$types]" $Values
}
}
$tuples = ('dog', 'cat'), ('dog', 'horse') | New-Tuple
感谢 mklement0,下面可能是最简单的解决方案
$b = , @{ dog = "cat"}
$b += @{ dog = "horse"}
并且 Persistent13 的方法也产生了一条简单的路线
$ht = @{foo='bar'}
$list = [System.Collections.Generic.List[hashtable]]::new()
$list.Add($ht)
$list.Add($ht)
$list.Add($ht)
$list
我想我只是感到惊讶,没有一种更根深蒂固的方法来获得我认为漂亮的 basic/standard 对象类型
我实际上是在尝试创建一个配对列表,事实证明这非常困难
在有人提到 Hashtables 之前请注意,会有我不关心的重复项。
例如,如果我这样做
$b = @{"dog" = "cat"}
我明白了
名称值 ---- ----- 狗猫
哪个好。但是,我无法添加
之类的内容$b += @{"dog" = "horse"}
Item has already been added. Key in dictionary: 'dog' Key being added: 'dog'
我只是想创建一个 table 数据 ,我可以使用 .Add()
或 +=
之类的东西将其添加到 。
我相信哈希表列表应该可以完成您所追求的。
$ht = @{foo='bar'}
$list = [System.Collections.Generic.List[hashtable]]::new()
$list.Add($ht)
$list.Add($ht)
$list.Add($ht)
$list
创建哈希表的 数组 是最简单的解决方案,但重要的是要注意 "extending" 数组意味着隐式地 重新创建 它,鉴于数组是固定大小的数据结构,这可能会成为多次迭代的性能问题:
# Using array-construction operator ",", create a single-element array
# containing a hashtable
$b = , @{ dog = "cat"}
# "Extend" array $b by appending another hashtable.
# Technically, a new array must be allocated that contains the original array's
# elements plus the newly added one.
$b += @{ dog = "horse"}
This GitHub issue 讨论了未来可能的增强功能,使 PowerShell 本机支持可有效扩展的类似列表的数据类型,或者甚至 default 这种数据类型。 (从 Windows PowerShell v5.1 / PowerShell Core 6.2.0 开始,PowerShell 默认为 [object[]]
类型的固定大小数组)。
如果你想要一个元组列表,我建议实际构建一个 tuples:
的列表$list = @()
$tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat'
$tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse'
$list += $tuple1
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
$list += $tuple2
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
# dog horse 2
请注意,在这个例子中 $list
是一个常规数组,这意味着,正如 +=
赋值运算符附加到它会重新创建大小增加 1 的数组,将新项放入新的空槽中,然后替换原来的数组。对于少量追加操作,这通常不是大问题,但随着追加操作数量的增加,性能影响变得显着。
使用 ArrayList
而不是普通数组可以避免此问题:
$list = New-Object Collections.ArrayList
$tuple1 = New-Object 'Tuple[String,String]' 'dog', 'cat'
$tuple2 = New-Object 'Tuple[String,String]' 'dog', 'horse'
$list.Add($tuple1) | Out-Null
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
$list.Add($tuple2) | Out-Null
$list
# Output:
#
# Item1 Item2 Length
# ----- ----- ------
# dog cat 2
# dog horse 2
ArrayList
对象的 Add()
方法输出附加项目的索引。 Out-Null
抑制在大多数情况下不需要的输出。如果您想使用这些索引号,您可以将它们收集到一个变量中而不是丢弃它们 ($i = $list.Add($t1)
)。
如果你想避免一直指定新元组的类型,你可以将它包装成一个可重用的函数,如下所示:
function New-Tuple {
Param(
[Parameter(Mandatory=$true)]
[ValidateCount(2,2)]
[string[]]$Values
)
New-Object 'Tuple[String,String]' $Values
}
$tuple1 = New-Tuple 'dog', 'cat'
$tuple2 = New-Tuple 'dog', 'horse'
或者,以更通用的方式,像这样:
function New-Tuple {
Param(
[Parameter(
Mandatory=$true,
ValueFromPipeline=$true,
ValueFromPipelineByPropertyName=$true
)]
[ValidateCount(2,20)]
[array]$Values
)
Process {
$types = ($Values | ForEach-Object { $_.GetType().Name }) -join ','
New-Object "Tuple[$types]" $Values
}
}
$tuples = ('dog', 'cat'), ('dog', 'horse') | New-Tuple
感谢 mklement0,下面可能是最简单的解决方案
$b = , @{ dog = "cat"}
$b += @{ dog = "horse"}
并且 Persistent13 的方法也产生了一条简单的路线
$ht = @{foo='bar'}
$list = [System.Collections.Generic.List[hashtable]]::new()
$list.Add($ht)
$list.Add($ht)
$list.Add($ht)
$list
我想我只是感到惊讶,没有一种更根深蒂固的方法来获得我认为漂亮的 basic/standard 对象类型