Y at-il un opérateur de coalescence nul dans Powershell?
J'aimerais pouvoir faire ces commandes c # dans powershell:
var s = myval ?? "new value";
var x = myval == null ? "" : otherval;
Pas besoin des extensions de communauté Powershell, vous pouvez utiliser les instructions Powershell standard si en tant qu'expression:
variable = if (condition) { expr1 } else { expr2 }
Voici donc les remplaçants de votre première expression:
var s = myval ?? "new value";
devient l’un des suivants (selon les préférences):
$s = if ($myval -eq $null) { "new value" } else { $myval }
$s = if ($myval -ne $null) { $myval } else { "new value" }
ou en fonction de ce que $ myval peut contenir, vous pouvez utiliser:
$s = if ($myval) { $myval } else { "new value" }
et la deuxième expression mappe de la même manière:
var x = myval == null ? "" : otherval;
devient
$x = if ($myval -eq $null) { "" } else { $otherval }
Pour être honnête, elles ne sont pas très vives et ne sont pas aussi confortables à utiliser que les formes C #.
Vous pouvez également envisager de l'envelopper dans une fonction très simple pour rendre les choses plus lisibles:
function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } }
$s = Coalesce $myval "new value"
ou éventuellement comme, si Null:
function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } }
$s = IfNull $myval "new value" $myval
$x = IfNull $myval "" $otherval
Comme vous pouvez le constater, une fonction très simple peut vous donner un peu de liberté de syntaxe.
UPDATE: Une option supplémentaire à prendre en compte dans le mix est une fonction IsTrue plus générique:
function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } }
$x = IfTrue ($myval -eq $null) "" $otherval
Combinez ensuite la capacité de Powershell à déclarer des alias qui ressemblent un peu à des opérateurs. Vous obtenez ainsi:
New-Alias "??" Coalesce
$s = ?? $myval "new value"
New-Alias "?:" IfTrue
$ans = ?: ($q -eq "meaning of life") 42 $otherval
Il est clair que cela ne plaira pas à tout le monde, mais pourrait être ce que vous cherchez.
Oui, PowerShell a un opérateur de coalescence nul, ou au moins un opérateur capable d'un tel comportement. Cet opérateur est -ne
:
# Format:
# ($a, $b, $c -ne $null)[0]
($null, 'alpha', 1 -ne $null)[0]
# Output:
alpha
C'est un peu plus polyvalent qu'un opérateur de coalescence nul, puisqu'il crée un tableau de tous les éléments non nuls:
$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
fonctionne de la même manière, ce qui est utile pour compter les entrées nulles:
($null, 'a', $null -eq $null).Length
# Result:
2
Quoi qu’il en soit, voici un cas typique qui reflète l’opérateur ??
de C #:
'Filename: {0}' -f ($filename, 'Unknown' -ne $null)[0] | Write-Output
Cette explication est basée sur une suggestion de modification d'un utilisateur anonyme. Merci, qui que vous soyez!
En fonction de l'ordre des opérations, cela fonctionne dans l'ordre suivant:
,
crée un tableau de valeurs à tester.-ne
supprime tous les éléments du tableau qui correspondent à la valeur spécifiée - dans le cas présent, null. Le résultat est un tableau de valeurs non NULL dans le même ordre que le tableau créé à l'étape 1.[0]
est utilisé pour sélectionner le premier élément du tableau filtré.Simplifier cela:
Contrairement à l'opérateur de coalescence nul de C #, toutes les expressions possibles seront évaluées, car la première étape consiste à créer un tableau.
Il ne s'agit que de la moitié d'une réponse à la première moitié de la question, donc une réponse d'un quart si vous voulez, mais il existe une alternative beaucoup plus simple à l'opérateur de coalescence nulle, à condition que la valeur par défaut que vous souhaitez utiliser soit réellement la valeur par défaut du type :
string s = myval ?? "";
Peut être écrit dans Powershell comme:
([string]myval)
Ou
int d = myval ?? 0;
se traduit par Powershell:
([int]myval)
J'ai trouvé le premier de ces éléments utile lors du traitement d'un élément XML qui pourrait ne pas exister et qui, le cas échéant, pourrait être entouré d'espaces non désirés:
$name = ([string]$row.td[0]).Trim()
Le transtypage en chaîne protège contre la nullité de l'élément et empêche tout risque d'échec de Trim()
.
Si vous installez le Powershell Community Extensions Module , vous pouvez utiliser:
?? est l'alias de Invoke-NullCoalescing.
$s = ?? {$myval} {"New Value"}
?: est le pseudonyme d'Invoke-Ternary.
$x = ?: {$myval -eq $null} {""} {$otherval}
$null, $null, 3 | Select -First 1
résultats
3
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]
}
Souvent, je constate que je dois également traiter la chaîne vide comme nulle si j'utilise coalesce. J'ai fini par écrire une fonction pour cela, qui utilise la solution de Zenexer pour la fusion de la fusion nulle simple, puis a utilisé Keith Hill pour la vérification nulle ou vide, et l'a ajouté comme indicateur. donc ma fonction pourrait faire les deux.
L'un des avantages de cette fonction est qu'elle gère également le fait d'avoir tous les éléments nuls (ou vides), sans générer d'exception. Il peut également être utilisé pour de nombreuses variables d'entrée arbitraires, grâce à la façon dont PowerShell gère les entrées de tableau.
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)
}
}
Cela produit les résultats de test suivants:
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
Code de test:
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)
Le plus proche que je puisse obtenir est: $Val = $MyVal |?? "Default Value"
J'ai implémenté l'opérateur de coalescence null comme ci-dessus:
function NullCoalesc {
param (
[Parameter(ValueFromPipeline=$true)]$Value,
[Parameter(Position=0)]$Default
)
if ($Value) { $Value } else { $Default }
}
Set-Alias -Name "??" -Value NullCoalesc
L'opérateur ternaire conditionnel pourrait être implémenté de manière similaire.
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
Et utilisé comme: $Val = $MyVal |?: $MyVal "Default Value"