2

I found this codegolf answer for the FizzBuzz test, and after examining it a bit I realized I had no idea how it actually worked, so I started investigating:

for(int i=1; i<101;i++)
    System.Console.Write($"{(i%3*i%5<1?0:i):#}{i%3:;;Fizz}{i%5:;;Buzz}\n");

I put it into dotnetfiddle and established the 1st part works as follows:

{(BOOL?0:i):#}

When BOOL is true, then the conditional expression returns 0 otherwise the number.

However the number isn't returned unless it's <> 0. I'm guessing this is the job the of :# characters. I can't find any documentation on the :# characters workings. Can anyone explain the colon/hash or point me in the right direction?

Second part:

{VALUE:;;Fizz}

When VALUE = 0 then nothing is printed. I assume this is determined by the first ; character [end statement]. The second ; character determines 'if VALUE <> 0 then print what's after me.'

Again, does anyone have documentation on the use of a semicolon in string interpolation, as I can't find anything useful.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Jon Barker
  • 1,788
  • 15
  • 25
  • 1
    `what other 'advanced' functionality exists in string interpolation that I may not be aware of?` is going to be far too broad, you should probably remove this – Liam Dec 20 '18 at 16:59
  • 2
    [Composite formatting](https://learn.microsoft.com/en-us/dotnet/standard/base-types/composite-formatting?view=netframework-4.7.2) – DavidG Dec 20 '18 at 17:01
  • 1
    Anything behind a colon `:` is just a plain old simple format string (https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings). (Not including the colon of the ternary inline-if operator `condition ? exprA : exprB`, of course) –  Dec 20 '18 at 17:02
  • @elgonzo - that would be the case, but there's no ? mark before the colon in the first, or second parts of this. – Jon Barker Dec 20 '18 at 17:06
  • @JonBarker, but there is a ternary inline-if operator in your code example. I am not sure what you are trying to say here... –  Dec 20 '18 at 17:07
  • 1
    for your `;;`, see [String Formatting](https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings) – Phil M Dec 20 '18 at 17:08
  • Thanks for the link @DavidG, there's nothing in there about # or ; though – Jon Barker Dec 20 '18 at 17:08
  • Thanks for your input all - it makes sense now! – Jon Barker Dec 20 '18 at 17:16

2 Answers2

3

This is all covered in the String Interpolation documentation, especially the section on the Structure of an Interpolated String, which includes this:

{<interpolatedExpression>[,<alignment>][:<formatString>]}

along with a more detailed description for each of those three sections.

The format string portion of that structure is defined on separate pages, where you can use standard and custom formats for numeric types as well as standard and custom formats for date and time types. There are also options for Enum values, and you can even create your own custom format provider.

It's worth taking a look at the custom format provider documentation just because it will also lead you to the FormattableString type. This isn't well-covered by the documentation, but my understanding is this type may in theory allow you to avoid re-parsing the interpolated string for each iteration when used in a loop, thus potentially improving performance (though in practice, there's no difference at this time). I've written about this before, and my conclusion is MS needs to build this into the framework in a better way.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
2

Thanks to all the commenters! Fast response.

The # is defined here (Custom specifier)

https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#the--custom-specifier

The "#" custom format specifier serves as a digit-placeholder symbol. If the value that is being formatted has a digit in the position where the "#" symbol appears in the format string, that digit is copied to the result string. Otherwise, nothing is stored in that position in the result string. Note that this specifier never displays a zero that is not a significant digit, even if zero is the only digit in the string. It will display zero only if it is a significant digit in the number that is being displayed.

The ; is defined here (Section Seperator):

https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-numeric-format-strings#the--section-separator

The semicolon (;) is a conditional format specifier that applies different formatting to a number depending on whether its value is positive, negative, or zero. To produce this behavior, a custom format string can contain up to three sections separated by semicolons...

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Jon Barker
  • 1,788
  • 15
  • 25