PowerShell中是否有空合并运算符?
我希望能够在powershell中执行这些c#命令:
var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
答案 0 :(得分:103)
不需要Powershell社区扩展,您可以使用标准的Powershell if语句作为表达式:
variable = if (condition) { expr1 } else { expr2 }
所以对你的第一个表达式的替换是:
var s = myval ?? "new value";
成为以下之一(取决于偏好):
$s = if ($myval -eq $null) { "new value" } else { $myval }
$s = if ($myval -ne $null) { $myval } else { "new value" }
或取决于my myval可能包含的内容:
$s = if ($myval) { $myval } else { "new value" }
并且第二个表达式以类似的方式映射:
var x = myval == null ? "" : otherval;
变为
$x = if ($myval -eq $null) { "" } else { $otherval }
现在公平地说,这些并不是非常活泼,并且没有像C#表格那样舒适的使用。
您也可以考虑将其包装在一个非常简单的函数中,以使事物更具可读性:
function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } }
$s = Coalesce $myval "new value"
或者可能是,IfNull:
function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } }
$s = IfNull $myval "new value" $myval
$x = IfNull $myval "" $otherval
正如您所看到的,一个非常简单的函数可以为您提供相当多的语法自由。
更新:混合中需要考虑的另一个选项是更通用的IsTrue函数:
function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } }
$x = IfTrue ($myval -eq $null) "" $otherval
然后结合这是Powershell声明看起来有点像运算符的别名的能力,最终得到:
New-Alias "??" Coalesce
$s = ?? $myval "new value"
New-Alias "?:" IfTrue
$ans = ?: ($q -eq "meaning of life") 42 $otherval
显然,这不符合每个人的口味,但可能正是您所寻找的。 p>
答案 1 :(得分:80)
是的,PowerShell确实有一个实际的空合并运算符,或者至少是一个能够执行此类行为的运算符。该运算符为-ne
:
# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]
# Output:
alpha
它比空合并运算符更通用,因为它创建了一个包含所有非空项的数组:
$items = $null, 'alpha', 5, 0, '', @(), $null, $true, $false
$instances = $items -ne $null
[string]::Join(', ', ($instances | ForEach-Object -Process { $_.GetType() }))
# Result:
System.String, System.Int32, System.Int32, System.String, System.Object[],
System.Boolean, System.Boolean
-eq
的工作方式类似,这对于计算空条目非常有用:
($null, 'a', $null -eq $null).Length
# Result:
2
但无论如何,这是镜像C#的??
运算符的典型案例:
'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output
此解释基于匿名用户的编辑建议。谢谢,无论你是谁!
根据操作顺序,按以下顺序进行:
,
运算符创建要测试的值数组。-ne
运算符过滤掉数组中与指定值匹配的所有项 - 在本例中为null。结果是一个非空值数组,其顺序与步骤1中创建的数组相同。[0]
用于选择已过滤数组的第一个元素。简化:
与C#的空合并运算符不同,将评估每个可能的表达式,因为第一步是创建数组。
答案 2 :(得分:13)
这只是问题前半部分的答案的一半,所以如果你愿意,四分之一的答案,但是如果你想要使用的默认值实际上是默认值,那么有一个更简单的替代空合并运算符的方法。对于类型:
string s = myval ?? "";
可以用Powershell写成:
([string]myval)
或者
int d = myval ?? 0;
转换为Powershell:
([int]myval)
我在处理可能不存在的xml元素时发现第一个有用,如果它确实存在,可能会有不需要的空格:
$name = ([string]$row.td[0]).Trim()
强制转换为字符串可以防止元素为空,并防止Trim()
失败的风险。
答案 3 :(得分:9)
如果您安装Powershell Community Extensions Module,则可以使用:
??是Invoke-NullCoalescing的别名。
$s = ?? {$myval} {"New Value"}
?:是Invoke-Ternary的别名。
$x = ?: {$myval -eq $null} {""} {$otherval}
答案 4 :(得分:9)
$null, $null, 3 | Select -First 1
返回
3
答案 5 :(得分:3)
@($null,$null,"val1","val2",5) | select -First 1
答案 6 :(得分:2)
function coalesce {
Param ([string[]]$list)
#$default = $list[-1]
$coalesced = ($list -ne $null)
$coalesced[0]
}
function coalesce_empty { #COALESCE for empty_strings
Param ([string[]]$list)
#$default = $list[-1]
$coalesced = (($list -ne $null) -ne '')[0]
$coalesced[0]
}
答案 7 :(得分:2)
通常我发现在使用coalesce时我还需要将空字符串视为null。我最后为此编写了一个函数,它使用Zenexer的解决方案来合并简单的空合并,然后使用Keith Hill' s进行空或空检查,以及补充说,作为一个标志,所以我的功能可以做到这两点。
此函数的一个优点是,它还可以处理所有元素为null(或为空),而不会抛出异常。由于PowerShell处理数组输入的方式,它也可以用于任意多个输入变量。
function Coalesce([string[]] $StringsToLookThrough, [switch]$EmptyStringAsNull) {
if ($EmptyStringAsNull.IsPresent) {
return ($StringsToLookThrough | Where-Object { $_ } | Select-Object -first 1)
} else {
return (($StringsToLookThrough -ne $null) | Select-Object -first 1)
}
}
这会产生以下测试结果:
Null coallesce tests:
1 (w/o flag) - empty/null/'end' :
1 (with flag) - empty/null/'end' : end
2 (w/o flag) - empty/null :
2 (with flag) - empty/null :
3 (w/o flag) - empty/null/$false/'end' :
3 (with flag) - empty/null/$false/'end' : False
4 (w/o flag) - empty/null/"$false"/'end' :
4 (with flag) - empty/null/"$false"/'end' : False
5 (w/o flag) - empty/'false'/null/"$false"/'end':
5 (with flag) - empty/'false'/null/"$false"/'end': false
测试代码:
Write-Host "Null coalesce tests:"
Write-Host "1 (w/o flag) - empty/null/'end' :" (Coalesce '', $null, 'end')
Write-Host "1 (with flag) - empty/null/'end' :" (Coalesce '', $null, 'end' -EmptyStringAsNull)
Write-Host "2 (w/o flag) - empty/null :" (Coalesce('', $null))
Write-Host "2 (with flag) - empty/null :" (Coalesce('', $null) -EmptyStringAsNull)
Write-Host "3 (w/o flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end')
Write-Host "3 (with flag) - empty/null/`$false/'end' :" (Coalesce '', $null, $false, 'end' -EmptyStringAsNull)
Write-Host "4 (w/o flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end')
Write-Host "4 (with flag) - empty/null/`"`$false`"/'end' :" (Coalesce '', $null, "$false", 'end' -EmptyStringAsNull)
Write-Host "5 (w/o flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end')
Write-Host "5 (with flag) - empty/'false'/null/`"`$false`"/'end':" (Coalesce '', 'false', $null, "$false", 'end' -EmptyStringAsNull)
答案 8 :(得分:2)
最后,PowerShell 7得到了Null Coalescing assignment operators!
PS > $null ?? "a"
a
PS > "x" ?? "y"
x
PS > $x = $null
PS > $x ??= "abc"
PS > $x
abc
PS > $x ??= "xyz"
PS > $x
abc
答案 9 :(得分:0)
我能得到的最接近的是:$Val = $MyVal |?? "Default Value"
我为上述代码实现了null coalescing operator:
function NullCoalesc {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$Default
)
if ($Value) { $Value } else { $Default }
}
Set-Alias -Name "??" -Value NullCoalesc
conditional ternary operator可以以类似的方式实现。
function ConditionalTernary {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$First,
[Parameter(Position=1)]$Second
)
if ($Value) { $First } else { $Second }
}
Set-Alias -Name "?:" -Value ConditionalTernary
其用法类似于:$Val = $MyVal |?: $MyVal "Default Value"