如何检查PowerShell管道是否为每个管道元素返回true?
在PowerShell中,我希望比较对象并在匹配时返回true。最后,如果每个管道元素都返回true,那么管道应该只返回一个布尔值true,否则返回false。仅使用管道如何实现这一点 例如:如何检查PowerShell管道是否为每个管道元素返回true?,powershell,Powershell,在PowerShell中,我希望比较对象并在匹配时返回true。最后,如果每个管道元素都返回true,那么管道应该只返回一个布尔值true,否则返回false。仅使用管道如何实现这一点 例如: @("a","b","c") | % { $_ -match "[a-z]" } # -> should only return true once @("a","1","c") | % { $_ -match "[a-z]" } # -> should only return false o
@("a","b","c") | % { $_ -match "[a-z]" } # -> should only return true once
@("a","1","c") | % { $_ -match "[a-z]" } # -> should only return false once
下面的示例使用
Where Object
(别名:?{…}
)来:
- 删除与您的条件不匹配的集合迭代
- 将结果集合的计数与原始集合的计数进行比较。如果未删除任何内容(如果所有内容都符合您的条件),则该语句返回true
PS C:\> $arr = @("a","b","c")
PS C:\> @($arr | ? { $_ -match "[a-z]" }).Count -eq @($arr).Count
True
PS C:\> $arr = @("a","1","c")
PS C:\> @($arr | ? { $_ -match "[a-z]" }).Count -eq @($arr).Count
False
下面的示例使用
Where Object
(别名:?{…}
)来:
- 删除与您的条件不匹配的集合迭代
- 将结果集合的计数与原始集合的计数进行比较。如果未删除任何内容(如果所有内容都符合您的条件),则该语句返回true
PS C:\> $arr = @("a","b","c")
PS C:\> @($arr | ? { $_ -match "[a-z]" }).Count -eq @($arr).Count
True
PS C:\> $arr = @("a","1","c")
PS C:\> @($arr | ? { $_ -match "[a-z]" }).Count -eq @($arr).Count
False
如果您只想使用一个管道而不是多个语句,您可能可以这样做:
$data | % { check } | sort -unique | select -first 1
这将检查每个元素,对结果进行排序并删除重复项,因此此时唯一的结果是$false
,$false,
,和$true
。然后我们只取第一个值。如果每个元素都通过了检查,则该元素仅为$true
如果您对管道中的其他语句或表达式没有那么大的反对意见,则可以执行收集计数检查,或者反转条件,然后否定结果:
!($data | ? { !(check) })
管道将返回
$null
,或者返回许多项。然后,布尔值not将强制将其转换为布尔值。这种方法的唯一问题是,当只有一个项目与反向检查相匹配时,它相当于$false
(例如,空字符串或0
)。如果您只想使用一个管道而不是多个语句,您可能可以这样做:
$data | % { check } | sort -unique | select -first 1
这将检查每个元素,对结果进行排序并删除重复项,因此此时唯一的结果是$false
,$false,
,和$true
。然后我们只取第一个值。如果每个元素都通过了检查,则该元素仅为$true
如果您对管道中的其他语句或表达式没有那么大的反对意见,则可以执行收集计数检查,或者反转条件,然后否定结果:
!($data | ? { !(check) })
管道将返回
$null
,或者返回许多项。然后,布尔值not将强制将其转换为布尔值。这种方法的唯一问题是,只有一项与反向检查匹配,并且它相当于$false
(例如,一个空字符串,或0
)。如果您有PowerShell 4,可以将Linq与
$data = ("a","b","c")
$testFunction = [func[object,bool]] {param($item) $item -match "[a-z]"}
[Linq.Enumerable]::All($data, $testFunction)
如果您有PowerShell 4,则可以将Linq与
$data = ("a","b","c")
$testFunction = [func[object,bool]] {param($item) $item -match "[a-z]"}
[Linq.Enumerable]::All($data, $testFunction)
受其他答案的启发,我想出了另一个解决方案,它也只返回真或假
@("a","b","c") | % { $_ -match "[a-z]" } | Measure-Object -Sum | % { $_.Count -eq $_.sum }
@("a","1","c") | % { $_ -match "[a-z]" } | Measure-Object -Sum | % { $_.Count -eq $_.sum }
受其他答案的启发,我想出了另一个解决方案,它也只返回真或假
@("a","b","c") | % { $_ -match "[a-z]" } | Measure-Object -Sum | % { $_.Count -eq $_.sum }
@("a","1","c") | % { $_ -match "[a-z]" } | Measure-Object -Sum | % { $_.Count -eq $_.sum }
这是一个非常有趣的答案。直到现在我才知道Linq。我总是忘记它,特别是因为它不像PowerShell的管道那样好用,而且做的事情基本上都是一样的。我认为一个不错的添加应该是
Where Object
上的-All
参数,也可能是-None
,尽管这会隐式地颠倒条件的含义。这是一个非常有趣的答案。直到现在我才知道Linq。我总是忘记它,特别是因为它不像PowerShell的管道那样好用,而且做的事情基本上都是一样的。我认为一个不错的添加应该是-Where对象上的-All
参数,也可能是-None
,尽管这会隐式地颠倒条件的含义。您也可以使用-notcontains
来实现这一点:(@(“a”,“b”,“c”){$\match”[a-z]}-notcontains$false
返回True
。不过,这并没有使用管道。您也可以使用-notcontains
来实现这一点:(@(“a”、“b”、“c”)|%{$\u-match”[a-z]“})-notcontains$false
返回True
。但这并不是在使用管道。