powershell null-coalescing-operator

Nulo que se fusiona en powershell



null-coalescing-operator (7)

A menudo me parece que también necesito tratar la cadena vacía como nula cuando uso fusionar. Terminé escribiendo una función para esto, que utiliza la solución de Zenexer para Zenexer para la Zenexer nula simple, y luego utilicé Keith Hill para una comprobación nula o vacía, y lo agregué como una bandera para que mi función pudiera hacer ambas cosas.

Una de las ventajas de esta función es que también maneja tener todos los elementos nulos (o vacíos), sin lanzar una excepción. También se puede usar para muchas variables de entrada arbitrarias, gracias a cómo PowerShell maneja las entradas de matriz.

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) } }

Esto produce los siguientes resultados de prueba:

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

Código de prueba:

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)

¿Hay un operador coalescente nulo en PowerShell?

Me gustaría poder hacer estos comandos c # en powershell:

var s = myval ?? "new value"; var x = myval == null ? "" : otherval;


Esto es solo la mitad de una respuesta a la primera mitad de la pregunta, por lo que una respuesta trimestral, si lo desea, pero hay una alternativa mucho más sencilla para el operador coalescente nulo, siempre que el valor predeterminado que desea utilizar sea el valor predeterminado para el tipo :

string s = myval ?? "";

Puede escribirse en Powershell como:

([string]myval)

O

int d = myval ?? 0;

se traduce a Powershell:

([int]myval)

Encontré el primero útil cuando procesaba un elemento xml que podría no existir y que, si existiera, podría tener un espacio en blanco no deseado alrededor de él:

$name = ([string]$row.td[0]).Trim()

El lanzamiento a la cuerda protege contra que el elemento sea nulo y evita cualquier riesgo de falla de Trim() .


No es necesario para Powershell Community Extensions, puede usar las declaraciones Powershell if estándar como una expresión:

variable = if (condition) { expr1 } else { expr2 }

Entonces, para los reemplazos de su primera expresión es:

var s = myval ?? "new value";

se convierte en uno de los siguientes (dependiendo de la preferencia):

$s = if ($myval -eq $null) { "new value" } else { $myval } $s = if ($myval -ne $null) { $myval } else { "new value" }

o dependiendo de lo que $ myval pueda contener, puede usar:

$s = if ($myval) { $myval } else { "new value" }

y la segunda expresión se correlaciona de manera similar:

var x = myval == null ? "" : otherval;

se convierte

$x = if ($myval -eq $null) { "" } else { $otherval }

Ahora, para ser justos, estos no son muy rápidos, y en ningún lugar son tan cómodos de usar como los C #.

También podría considerar envolverlo en una función muy simple para que las cosas sean más legibles:

function Coalesce($a, $b) { if ($a -ne $null) { $a } else { $b } } $s = Coalesce $myval "new value"

o posiblemente como, IfNull:

function IfNull($a, $b, $c) { if ($a -eq $null) { $b } else { $c } } $s = IfNull $myval "new value" $myval $x = IfNull $myval "" $otherval

Como puede ver, una función muy simple puede proporcionarle un poco de libertad de sintaxis.

ACTUALIZACIÓN: Una opción adicional a considerar en la mezcla es una función IsTrue más genérica:

function IfTrue($a, $b, $c) { if ($a) { $b } else { $c } } $x = IfTrue ($myval -eq $null) "" $otherval

Luego combine esa es la capacidad de Powershell para declarar alias que se parecen un poco a los operadores, usted termina con:

New-Alias "??" Coalesce $s = ?? $myval "new value" New-Alias "?:" IfTrue $ans = ?: ($q -eq "meaning of life") 42 $otherval

Claramente, esto no va a ser del gusto de todos, pero puede ser lo que estás buscando.


Sí, PowerShell sí tiene un operador coalescente nulo real, o al menos un operador que es capaz de tal comportamiento. Ese operador es -ne :

# Format: # ($a, $b, $c -ne $null)[0] ($null, ''alpha'', 1 -ne $null)[0] # Output: alpha

Es un poco más versátil que un operador coalescente nulo, ya que crea una matriz de todos los elementos no nulos:

$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 funciona de manera similar, lo cual es útil para contar entradas nulas:

($null, ''a'', $null -eq $null).Length # Result: 2

Pero de todos modos, aquí hay un caso típico para reflejar C # ''s ?? operador:

''Filename: {0}'' -f ($filename, ''Unknown'' -ne $null)[0] | Write-Output

Explicación

Esta explicación se basa en una sugerencia de edición de un usuario anónimo. Gracias, quienquiera que seas!

Según el orden de las operaciones, esto funciona en el siguiente orden:

  1. El operador , crea una matriz de valores para probar.
  2. El operador -ne filtra cualquier elemento de la matriz que coincida con el valor especificado, en este caso, nulo. El resultado es una matriz de valores no nulos en el mismo orden que la matriz creada en el Paso 1.
  3. [0] se utiliza para seleccionar el primer elemento de la matriz filtrada.

Simplificando eso:

  1. Crear una matriz de valores posibles, en el orden preferido
  2. Excluir todos los valores nulos de la matriz
  3. Tome el primer artículo de la matriz resultante

Advertencias

A diferencia del operador coalescente nulo de C #, se evaluarán todas las expresiones posibles, ya que el primer paso es crear una matriz.



$null, $null, 3 | Select -First 1

devoluciones

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] }