PoshBytes: 12 Logical Days of Christmas
Use PowerShell loops and Unicode-safe logic to generate the 12 Days of Christmas with while learning why CharArray breaks certain elements and how StringInfo fixes it.
This post is a companion for the video embedded below. Scroll down to see the code from the video.
Logical 12 Days of Christmas (No Emojis Yet)
Set ordinal names for days
$days = "First","Second","Third","Fourth","Fifth","Sixth",
"Seventh","Eighth","Ninth","Tenth","Eleventh","Twelfth"
Define our gifts
$gifts = @(
"a Partridge in a Pear Tree",
"two Turtle Doves",
"three French Hens",
"four Calling Birds",
"five Gold Rings",
"six Geese a-Laying",
"seven Swans a-Swimming",
"eight Maids a-Milking",
"nine Ladies Dancing",
"ten Lords a-Leaping",
"eleven Pipers Piping",
"twelve Drummers Drumming"
)
loop through each 12 days
for ($i = 0; $i -lt 12; $i++) {
Write-Host "`nOn the $($days[$i]) day of Christmas, my true love sent to me:"
# Count down from the current day to display the gifts
for ($j = $i; $j -ge 0; $j--) {
Write-Host " - " -NoNewline
# Add "and" before the last gift if it's not the first day
if ($i -gt 0 -and $j -eq 0) {
Write-Host "and " -NoNewline
}
# Split string into characters and loop through each for typing effect
$gifts[$j].ToCharArray() | ForEach-Object {
Write-Host -NoNewline $_
Start-Sleep -Milliseconds 100
}
Write-Host ''
}
Start-Sleep -Milliseconds 500
}
Handling Emojis Without Breaking Them
Replace gifts with emojis
$gifts = @(
"a π¦ in a π π³ ",
"two π’ ποΈποΈ",
"three π«π· π",
"four π£ π¦",
"five πͺ π",
"six π¦ a-π₯",
"seven π¦’ a-π",
"eight π§Ή a-π",
"πππππππππ",
"ten π€΄ a-π¦",
"eleven π§βπ€ πͺ",
"twelve π’οΈ π₯"
)
Why `.ToCharArray()` Fails With Emojis
Example of .ToCharArray() splitting characters
"TeΜd".ToCharArray()
# CharArray doesn't handle emojis well, so use StringInfo
$chars = [System.Globalization.StringInfo]::GetTextElementEnumerator($gifts[$j])
while ($chars.MoveNext()) {
Write-Host -NoNewline $chars.GetTextElement()
Start-Sleep -Milliseconds 100
}
Wrap Up
β’ $i represents the current day β’ We print the intro line for that day β’ $j starts at the current day β’ It decreases to zero β’ This recreates the βstackingβ effect of the song β’ Loops and arrays to build the 12 Days of Christmas β’ Nested loops to accumulate previous daysβ gifts β’ Adding emojis to make the output festive and readable β’ Why .ToCharArray() breaks emojis due to UTF-16 surrogate pairs β’ Using System.Globalization.StringInfo to iterate emoji-safe text elements