3

我想List<Tuple<int,string>>在 PowerShell 中创建一个,但是

New-Object System.Collections.Generic.List[System.Collections.Generic.Tuple[int,string]]

不起作用。我错过了什么?

4

4 回答 4

11

Lee 的回答是创建元组列表的正确方法(尽管您可以通过省略 System 命名空间使语句更短)。但是,在 PowerShell 中编程时要问的更好的问题是:

  • 为什么要返回强类型对象?
  • 我真的要输出一个列表吗?

第一个有它的优点和缺点。如果强类型对象具有对管道的下一步有用的方法或事件,则它们很有用返回。另一方面,如果您只想返回一堆名称为 int 的项目,我会使用类似:

New-Object PSObject -Property @{string="string";int=1} 

这将创建一个包含您需要的数据的属性包(大多数开发人员都称为元组),其描述性名称比 .NET 元组在对象上为您提供的名称更多。它也非常快。另一方面,如果数据是用于 API 的,那么无论如何都会创建它所期望的强类型对象。

第二个问题有点难以理解,但有一个更明确的答案。在许多情况下,您会希望从一个函数的输出中接受另一个函数的输入。在此,由于许多原因,强类型列表不是您最好的朋友。强类型列表并不总是清楚地转换为数组(对于泛型尤其如此),并且作为函数的参数,严重限制了您可以放入函数中的不同类型的数据。它们最终还提供了一些误导性和难以使用的输出(尤其是在对象中管道并产生多个结果时),因为整个列表将显示为一个输出项目,而不是单独显示每个项目。最烦人的是,当您“过度索引”时,强类型列表的行为与 PowerShell 中的数组不同(即。e. 在 5 个项目的列表中要求项目 10000)数组将悄悄地返回 null。列表会大声呕吐。更实际地,将项目累积到列表中然后输出列表将“保持”管道,直到所有项目都进入。这可能是您想要的,但在大多数情况下,很高兴看到函数运行时输出的输出。最后,列表会增加函数的内存开销,因为您需要在函数的堆栈中累积一组对象。

我通常做的只是发出多个对象。也就是说,我避免使用 return 关键字,而是利用 PowerShell 返回未捕获到变量中的对象的能力。如果我将结果分配给一个变量,这些项目将在一个数组列表中累积并作为一个数组返回给你。这个快速的小演示功能向您展示了如何。

function Get-RandomData {
     param($count = 10)

     foreach ($n in 1..$count){
         New-Object PSObject -Property @{Name="Number$n";Number=Get-Random}
     }
}

值得注意的是,专门的集合仍然非常有用。当需要时,我经常使用队列和堆栈。但是,我很少发现自己使用泛型或列表,除非我正在使用 .NET 中特别需要泛型或列表的部分。这对我个人来说非常具有讽刺意味,因为我是在 PowerShell V2 中测试对泛型支持的人。当您想要使用只能获取元组列表的 .NET 时,这是绝对需要的。在所有其他情况下,这会适得其反。

于 2013-10-30T07:55:00.677 回答
8

您可以使用以下方法创建它:

New-Object 'Collections.Generic.List[Tuple[int,string]]'

您拼写错误 Generic ,并且Tuple类型在System命名空间中,而不是System.Collections.Generic.

于 2013-10-29T21:07:55.563 回答
6

这对我有用。我还提供了要插入到列表中的示例代码:

$myList = New-Object System.Collections.ArrayList

 #add range
 $myList.AddRange((
 [Tuple]::Create(1,"string 1"),
 [Tuple]::Create(2,"string 2"),
 [Tuple]::Create(3,"string 3") 
 ));

 #add single item
 $myList.Add([Tuple]::Create(4,"string 4"))

 #create variable and add to list
 $myTuple = [Tuple]::Create(5,"string 5") 
 $myList.Add( $myTuple)

 Write-Host $myList

参考: 在 PowerShell 中使用和理解元组

于 2017-09-19T08:48:17.353 回答
1

您可以创建一个最多包含 7 个元素的元组,如下所示:

$tuple = [tuple]::Create(1,2,3,4,5,6,7)

并且您可以通过命名它的项目来获取元素的值(从 item1 开始):

$tuple.item1
1

如果您有 8 个或更多元素,则为第 8 个元素使用另一个元组:

$tuple = [tuple]::Create(1,2,3,4,5,6,7,[tuple]::create(8,9))

在内部,第 8 个元素称为“休息”。你可以得到这样的值:

$tuple.rest.item1.item1
8

如果您需要为每个元素指定一个类型,请在每个值前面执行:

$tuple = [tuple]::create([string]"a", [int]1, [byte]255)

最后,将元组添加到列表中的工作方式如下:

$list = New-Object 'Collections.ArrayList'
$tuple = [tuple]::create([string]"a", [int]1, [byte]255)
$list.add($tuple)

无需指定元组详细信息来创建列表。

请记住,您以后无法更改元组的值,并且默认排序方法按 items1、item2 等的顺序对升序进行排序(或者您需要自定义 IComparer),但是使用它们非常快(比处理大量 PsObject 或 PSCustomObject 列表,并且比 import-Csv 更快)!

于 2018-10-16T08:49:15.153 回答