# Smartly joining possibly empty strings

I want to join two fragments into one string with a separator, but when one of the fragments is empty I only want one of them.

I have two implementations. The first is long and slightly repetitive, but I believe it is easier to understand, since it is a more step-by-step description of the process. The second is way shorter, but less self-explanatory. It uses the Where method, and it may not be clear to everybody what the semantics of $_ are. Maybe both approaches can even be merged into an even better implementation. Which would you recommend? Version 1: if ($Fragment1.Length -ne 0 -and $Fragment2.Length -ne 0) {$String = $Fragment2 +$Seperator + $Fragment2 } elseif ($Fragment1.Length -ne 0) {
$String =$Fragment1
} elseif ($Fragment2.Length -ne 0) {$String = $Fragment2 } else {$String = $null }  Version 2: $String =
@($Fragment2,$Fragment1).Where({$_.Length -ne 0}) -join$Seperator

• As someone who doesn't use PowerShell I find the second easier to read. Jun 5, 2020 at 15:44
• OK, so you'd recommend V2? Jun 5, 2020 at 15:45
• Not really. I would use it. But I wouldn't recommend you to use it as you find it harder to read. Jun 5, 2020 at 15:46
• I'd like to make it clear that I'm not saying I dislike it. I am concerned about the readability of my code. I prefer version 2 myself. Jun 5, 2020 at 15:49
• No matter which implementation you choose, you should extract this code into a function called JoinSkipEmpty. This way it doesn't matter that much if the code is complicated or not since the name already expresses everything you need to know about the function. Oh, and please write Separator instead of Seperator. Your IDE should have told you this spelling mistake. Jun 5, 2020 at 16:20

On PowerShell v6+, I would do the following:

$String =$Fragment1, $Fragment2 | Where-Object { -not [System.String]::IsNullOrWhiteSpace($_) } |
Join-String -Separator $Separator  You could use [System.String]::IsNullOrEmpty() instead of [System.String]::IsNullOrWhiteSpace(), but I find [System.String]::IsNullOrWhiteSpace() to be the desired functionality in almost all cases. On Windows PowerShell (versions prior to v6), the Join-String command doesn't exist. There I would use: $String = ($Fragment1,$Fragment2 |
Where-Object { -not [System.String]::IsNullOrWhiteSpace($_) }) -join$Separator


The @().Where({ ... }) method is fairly obscure, so I tend to avoid it.

it may not be clear to everybody what the semantics of $_ are. I'm not sure it's valuable to consider this possibility. Simply put, if your reader doesn't understand the semantics of $_, then they cannot read PowerShell. It's a ubiquitous and pervasive variable both in practice and in design.

here is what i meant about the -join operator being the way to go. [grin] you DO need to filter out the blank/null items, but once that is done things work neatly. i included two filters ... the basic $_ test just uses the way that "nothing" and "blank" are coerced to booleans. the other uses the builtin [string]::IsNullOrEmpty() static method. # build some string arays to test with$1st = 'One', 'Two', 'Three'
$2nd = 'Wun',$Null, 'Tree'
$3rd = '', 'Too', ''$4th = 'A', 'B', ''

$Separator = '-' # the leading comma forces the arrays to remain individual arrays instead of merging into one foreach ($Item in (,$1st + ,$2nd + ,$3rd + ,$4th))
{
'Original ...'
$Item 'Unfiltered [will glitch with empty items] ...'$Item -join $Separator 'Filtered with basic ".Where()" test ...'$Item.Where({$_}) -join$Separator
'Filtered with explicit test ...'
$Item.Where({-not [string]::IsNullOrEmpty($_)}) -join \$Separator
'=' * 30
}


output ...

Original ...
One
Two
Three
Unfiltered [will glitch with empty items] ...
One-Two-Three
Filtered with basic ".Where()" test ...
One-Two-Three
Filtered with explicit test ...
One-Two-Three
==============================
Original ...
Wun
Tree
Unfiltered [will glitch with empty items] ...
Wun--Tree
Filtered with basic ".Where()" test ...
Wun-Tree
Filtered with explicit test ...
Wun-Tree
==============================
Original ...

Too

Unfiltered [will glitch with empty items] ...
-Too-
Filtered with basic ".Where()" test ...
Too
Filtered with explicit test ...
Too
==============================
Original ...
A
B

Unfiltered [will glitch with empty items] ...
A-B-
Filtered with basic ".Where()" test ...
A-B
Filtered with explicit test ...
A-B
==============================