2
\$\begingroup\$

I need help to format all the input values to the format ‘##-##/##'. My input might include whole number, fraction or mixed fraction...Sample input 3, 1/1, 1 1/2. I have tried the below code it is giving expected result. Can someone please help for a standard and concise way of doing this

using System.IO;
using System;
using System.Linq;

class Program
{
static void Main()
{
var input1 = "3";        /*Expected result 03-00/00 */
var input2 = "1/1";      /*Expected result 00-01/01*/
var input3 = "1 3/4";    /*Expected result 01-03/04*/
    
string[] splittedValue1= input1.Split( '/', ' ' );
string[] splittedValue2= input2.Split( '/', ' ' );
string[] splittedValue3= input3.Split( '/', ' ' );

/*Expected result 03-00/00 */
if(splittedValue1.Count()==1)
{
String test =splittedValue1[0].PadLeft(2, '0') +"-00/00" ;
Console.WriteLine(test);
}

/*Expected result 00-01/01*/
if(splittedValue2.Count()==2)
{
String format="00-00";
String test =Convert.ToInt32(splittedValue2[0]).ToString(format) + "/" + splittedValue2[1].PadLeft(2, '0');
Console.WriteLine(test); 
}


/*Expected result 01-03/04*/
if(splittedValue3.Count()==3)
{
 
String test =splittedValue3[0].PadLeft(2, '0') +"-" +splittedValue3[1].PadLeft(2, '0') + "/" + splittedValue3[2].PadLeft(2, '0');
Console.WriteLine(test); 
}

}

}
\$\endgroup\$
0
3
\$\begingroup\$

The main statements are:

  • DRY = Don't Repeat Yourself. Avoid repetitive code if possible.
  • The code would work only exactly for this set of test cases. As each test case is handled by separate branch. What if values will be different or entered by user from Console?
  • Use method to encapsulate the code to be able to call it multiple times.
  • As the fraction has a regular format, the Regular Expression can be useful here. To test ReGex'es I use https://regex101.com/ site, it explains how each part of the expression works. Also there's a documentation for .NET.
static void Main(string[] args)
{
    string[] inputs = new[] { "3", "1/1", "1 3/4" };
    foreach (string input in inputs)
        Console.WriteLine(FormatFraction(input));
    Console.ReadKey(true);
}
        
private static string FormatFraction(string input)
{
    string[] tokens = Regex.Match(input, @"^((-?\d+) ?)?((\d+)\/(\d+))?$")
        .Groups
        .Cast<Group>()
        .Select(s => s.Value.PadLeft(2, '0'))
        .ToArray();
    return string.Format("{2}-{4}/{5}", tokens);
}

The ReGex match groups are declared with braces (). For this pattern groups indexes are 0(1(2))(3(4)(5)) = 6 match groups, each Group contains a match inside it. The requred groups that contain the desired numbers \d+ (means the sequense of one and more digits) are 2, 4 and 5.

Output

03-00/00
00-01/01
01-03/04
\$\endgroup\$
4
  • 1
    \$\begingroup\$ Your answer is headed in the right direction but would you please explain what you are doing a little bit more, I have a feeling that the OP is newer to C# and might not know some of the operations that you are using to make your code cleaner and more precise. \$\endgroup\$ – Malachi Mar 29 at 21:42
  • \$\begingroup\$ Hi, Thanks for the review. I am trying to analyze the regex which you have used but i am facing issue during compilation. I have included the namepsace also "System.Text.RegularExpressions"...My .net framework is 4.5.The error i am getting is "System.Text.RegularExpressions.GroupCollection' does not contain a definition for Values' and no extension method Values' of type System.Text.RegularExpressions.GroupCollection' could be found. Are you missing an assembly reference? \$\endgroup\$ – Devi Mar 30 at 11:47
  • 1
    \$\begingroup\$ @Devi fixed for old frameworks. \$\endgroup\$ – aepot Mar 30 at 12:00
  • 1
    \$\begingroup\$ Thank you very much!. Got it \$\endgroup\$ – Devi Mar 30 at 12:09
0
\$\begingroup\$

Does this help?

StringFormat on GitHub

The actual string-logic worked, so I didn't touch it. Every time you want to subject a new string to your logic, you had to adjust your code. This is against open-closed-principle. When using a List and a simple foreach loop that is no longer the case. It's a simple improvement without adding any complexity, hence the suggestion.

using System;
using System.Collections.Generic;
using System.Linq;

namespace StringFormat
{
    class Program
    {
        static void Main(string[] args)
        {
            List<string> inputs = new List<string> { "3", "1/1", "1 3/4" };

        inputs.Add("2/2");
        inputs.Add("5");
        inputs.Add("2 4/5");

        foreach (string input in inputs)
        {
            string[] splittedValue = input.Split('/', ' ');

            /*Expected result 03-00/00 */
            if (splittedValue.Count() == 1)
            {
                String test = splittedValue[0].PadLeft(2, '0') + "-00/00";
                Console.WriteLine(test);
            }

            /*Expected result 00-01/01*/
            if (splittedValue.Count() == 2)
            {
                String format = "00-00";
                String test = Convert.ToInt32(splittedValue[0]).ToString(format) + "/" + splittedValue[1].PadLeft(2, '0');
                Console.WriteLine(test);
            }


            /*Expected result 01-03/04*/
            if (splittedValue.Count() == 3)
            {
                String test = splittedValue[0].PadLeft(2, '0') + "-" + splittedValue[1].PadLeft(2, '0') + "/" + splittedValue[2].PadLeft(2, '0');
                Console.WriteLine(test);
            }
        }
    }
}
\$\endgroup\$
5
  • \$\begingroup\$ Why are you doing .Count() fro array instead of .Length? Repeative code is a bad practice. This is not a review. \$\endgroup\$ – aepot Mar 29 at 20:00
  • \$\begingroup\$ His splittedValue-logic worked and I did not need to change it to produce an answer to his question, to get it into a more standard / concise. His issue was to generate a loop, so he did not need to write another string[] splittedValueX= inputX.Split( '/', ' ' ); every time he wanted to format another string. The issue for DRY is especially relevant for large chunks of code, and modular programming. Not for someone who is starting to program and delivers 20-30 lines. Don't impose your coding practices. I try to make a suggestion that helps the issue, remains close to his own code without \$\endgroup\$ – qqtf Mar 29 at 21:24
  • 3
    \$\begingroup\$ This is a Code Review of the string formatting code. Look at the String format C# title. The answer contains neither changes to string fromatting code nor suggestions or warnings. You simply added a loop outside of the code for review. This is not a review. \$\endgroup\$ – aepot Mar 29 at 21:31
  • 4
    \$\begingroup\$ Welcome to Code Review! this answer is a code only answer, and doesn't explain why the code you presented is better than that of the OP. Please feel free to edit your answer with the explanation of how your code is better than the code that the OP presented \$\endgroup\$ – Malachi Mar 29 at 21:32
  • \$\begingroup\$ adding unnecessary complexity like JimmyHu. His approach is totally different, which is fine. I'm not going to downvote him because he's using static methods, which is a bad practice, but understandable for the console application Devi is making. (Hence totally not relevant for the issue.) If the .Count() was something I added, your remark would be valid. But it wasn't. I flagged your comment. \$\endgroup\$ – qqtf Mar 29 at 21:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.