如何在PowerShell中测试$null数组

dvtswwa3  于 2022-12-23  发布在  Shell
关注(0)|答案(8)|浏览(127)

我在PowerShell 2.0中使用了一个数组变量。如果它没有值,它将是$null,我可以成功地测试它:

PS C:\> [array]$foo = $null
PS C:\> $foo -eq $null
True

但是当我给予它一个值时,对$null的测试并没有返回任何东西:

PS C:\> [array]$foo = @("bar")
PS C:\> $foo -eq $null
PS C:\>

“-eq $null”怎么会给予结果呢?它要么是$null,要么不是。
确定数组是否已填充与$null的正确方法是什么?

fae0ux8s

fae0ux8s1#

它是一个数组,因此您要查找Count来测试内容。
我建议

$foo.count -gt 0

这其中的“原因”与PSH如何处理集合对象的比较有关

pkbketx9

pkbketx92#

可以对操作对象重新排序:

$null -eq $foo

请注意,PowerShell中的-eq不是等价关系。

elcex8rz

elcex8rz3#

if($foo -eq $null) { "yes" } else { "no" }

help about_comparison_operators

显示帮助并包含以下文本:
除包含运算符之外的所有比较运算符(-contains,-notcontains)和类型运算符(-is,-isnot)在运算符的输入(运算符左侧的值)是单个值当输入是值的集合时,包含运算符和类型运算符返回任何匹配的值。如果集合中没有匹配项,这些操作符不返回任何东西。2包含操作符和类型操作符总是返回一个布尔值。

liwlm1x9

liwlm1x94#

如果你的解决方案要求返回0而不是true/false,我发现这很有用:

PS C:\> [array]$foo = $null
PS C:\> ($foo | Measure-Object).Count
0

此操作与数组的count属性不同,因为Measure-Object正在计数对象。由于没有对象,因此将返回0。

sh7euo9m

sh7euo9m5#

其他的答案都涉及到了问题的主旨,但只是对这一部分进行评论...

PS C:\> [array]$foo = @("bar")
PS C:\> $foo -eq $null
PS C:\>

"-eq $null"怎么会没有结果呢?它要么是$null,要么不是。
一开始很混乱,但是 * 是 * 给你$foo -eq $null的结果,只是结果没有可显示的表示。
因为$foo包含一个数组,所以$foo -eq $null意味着"返回一个包含$foo中等于$null的元素的数组"。$foo中是否有等于$null的元素?没有,所以$foo -eq $null应该返回一个空数组。这正是它所做的。问题是,当控制台上显示一个空数组时,您看到的是...什么都没有...

PS> @()
PS>

数组仍然存在,即使你看不到它的元素...

PS> @().GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> @().Length
0

我们可以使用类似的命令来确认$foo -eq $null * 返回了一个我们无法"看到"的数组...

PS> $foo -eq $null
PS> ($foo -eq $null).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> ($foo -eq $null).Length
0
PS> ($foo -eq $null).GetValue(0)
Exception calling "GetValue" with "1" argument(s): "Index was outside the bounds of the array."
At line:1 char:1
+ ($foo -eq $null).GetValue(0)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IndexOutOfRangeException

注意,我调用Array.GetValue method而不是使用索引器(即($foo -eq $null)[0]),因为后者对于无效索引返回$null,并且无法将它们与碰巧包含$null的有效索引区分开来。
如果我们在包含$null元素的数组中/针对该数组测试$null,我们会看到类似的行为...

PS> $bar = @($null)
PS> $bar -eq $null
PS> ($bar -eq $null).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> ($bar -eq $null).Length
1
PS> ($bar -eq $null).GetValue(0)
PS> $null -eq ($bar -eq $null).GetValue(0)
True
PS> ($bar -eq $null).GetValue(0) -eq $null
True
PS> ($bar -eq $null).GetValue(1)
Exception calling "GetValue" with "1" argument(s): "Index was outside the bounds of the array."
At line:1 char:1
+ ($bar -eq $null).GetValue(1)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : IndexOutOfRangeException

在本例中,$bar -eq $null返回一个包含一个元素$null的数组,该元素在控制台上没有可视表示...

PS> @($null)
PS> @($null).GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

PS> @($null).Length
1
okxuctiv

okxuctiv6#

你希望事情怎么样?
如果希望将不含元素的数组视为未赋值数组,请用途:

[array]$foo = @() #example where we'd want TRUE to be returned
@($foo).Count -eq 0

如果希望将空数组视为具有值(尽管是空的),请用途:

[array]$foo = @() #example where we'd want FALSE to be returned
$foo.PSObject -eq $null

如果希望将仅填充空值的数组视为空值:

[array]$foo = $null,$null
@($foo | ?{$_.PSObject}).Count -eq 0

注意:在上面的代码中,我使用$_.PSObject而不是$_来避免[bool]$false[int]0[string]''等被过滤掉;因为这里我们只关注空值。

wdebmtf2

wdebmtf27#

注意switch。它 * 永远不会运行 * 空数组,例如作为空目录的输出。

switch ( $null ) { default { 'yes' } }
yes

switch ( @() ) { default { 'yes' } }  # no output

mkdir foo
switch ( dir foo ) { default { 'yes' } }  # no output
5us2dqdw

5us2dqdw8#

并不是所有的答案都适合我,我最后这样做了,把它当作一个布尔值。

$foo = @()
if (! $foo) { 'empty array' }

empty array

实际上,我在一个对象中遇到了数组列表。

[pscustomobject]@{config = [Collections.ArrayList]@()} | ? { ! $_.config }

config
------
{}

相关问题