0

I've a little messy method, which generates a name out of three strings. The three strings can be null. I've to check each possible combination and create a string, based on the given available values. There isn't a fix position / layout for each variable in the resulting name, it depends on the availability of all strings.

My method looks like this right now:

    private String GetName(string variable, string label, string dimension)
    {
        string result = String.Empty;
        if (!String.IsNullOrEmpty(label) && !String.IsNullOrEmpty(variable) && !String.IsNullOrEmpty(dimension))
        {
            result = String.Format("{0} [{1}] ({2})", label, dimension, variable);
        }
        else if (!String.IsNullOrEmpty(label) && !String.IsNullOrEmpty(dimension))
        {
            result = String.Format("{0} [{1}]", label, dimension);
        }
        else if (!String.IsNullOrEmpty(label) && !String.IsNullOrEmpty(variable))
        {
            result = String.Format("{0} ({1})", label, variable);
        }
        else if (!String.IsNullOrEmpty(label))
        {
            result = String.Format("{0}", label);
        }
        else if (!String.IsNullOrEmpty(variable) && !String.IsNullOrEmpty(dimension))
        {
            result = String.Format("{0} [{1}]", variable, dimension);
        }
        else if (!String.IsNullOrEmpty(variable))
        {
            result = String.Format("{0}", variable);
        }
        return result;
    }

Any suggestions on how to improve this method (Get rid of the if / else construct)?

1
  • 1
    I think you missed case of else if (!String.IsNullOrEmpty(dimension)) Commented Jun 25, 2014 at 7:40

5 Answers 5

5

check the nulls at the top, change to strings if need be, then create a final result

var stringsToInclude = new List<string>();
if(!String.IsNullOrEmpty(label))
    stringsToInclude.Add(label);
if(!String.IsNullOrEmpty(dimension))
    stringsToInclude.Add(string.Format("[{0}]", dimension));
if(!String.IsNullOrEmpty(variable))
    stringsToInclude.Add(string.Format("({0})", variable));


result = string.Join(" ", stringsToInclude);

String.Join

Sign up to request clarification or add additional context in comments.

6 Comments

Adding to List<string>() and String.Join is simple and elegant solution.
@gildor if any are null they arent included in the join
@Sayse sorry I misunderstood. Vote up!
Good hint, but there would be some format errors, when only dimension and variable are available. It should be "Variable [Dimension]", with the List/String.Join method it would lead to "[Dimension] (Variable)" (Wrong order + variable in braces)
@cb_dev - are you saying that the second parameter needs square brackets and the third needs parenthesis? if so then tim's answer is correct.
|
0

If i've understood your logic correctly, you could also shorten it in this way:

private String GetName(string variable, string label, string dimension)
{
    string[] all = { variable, label, dimension };
    string[] notNull = all.Where(s => !string.IsNullOrEmpty(s)).ToArray();
    string format = notNull.Length == 3 ? "{0} [{1}] ({2})" 
                  : notNull.Length == 2 ? "{0} [{1}]" : "{0}";
    string result = String.Format(format, notNull);
    return result;
}

5 Comments

This was my first thought too but this would give the variable square brackets instead of ( as per the second else if
@Sayse: good catch. I haven't noticed that "variable" must have parenthesis since OP mentioned that "there isn't a fix position / layout for each variable".
Just for my understanding. Is it possible to determine by using notNull.Length that which string is out of all three strings? What if dimension variable parameter is given and other two are null?
@HassanNisar: In my approach it is not necessary to determine which string was null, but - as Sayse has already noticed - i've probably misunderstood OP requirement a little bit.
Intresting solution, but Sayse is right, in some cases it would lead to a wrong result
0
public String GetName(string label, string dimension, string variable)
    {
        string result = String.Empty;
        string labelFmt = !string.IsNullOrEmpty(label) ? string.Format("{0}", label) : string.Empty;
        string dimenFmt = !string.IsNullOrEmpty(dimension) ? string.Format("[{0}]", dimension) : string.Empty;
        string varFmt = !string.IsNullOrEmpty(variable) ? string.Format("({0})", variable) : string.Empty;
        string firstSepStr = (!string.IsNullOrEmpty(label) &&
                               (!string.IsNullOrEmpty(variable) || !string.IsNullOrEmpty(dimension)))
                                  ? " "
                                  : string.Empty;
        string secondSepStr = (!string.IsNullOrEmpty(variable) && !string.IsNullOrEmpty(dimension))
                                  ? " "
                                  : string.Empty;
        return string.Format("{0}{1}{2}{3}{4}", labelFmt, firstSepStr, dimenFmt, secondSepStr, varFmt);
    }

Comments

0

Taking into account that your can't just use empty strings in templates or use simple composition, your best bet is to use some sort of Func table(dictionary) that will contain formatting function:

public class MyStringFormatterKey : IEquatable<MyStringFormatterKey>
{
    private Boolean isVariableAbsent, isLabelAbsent, isDimensionAbsent;
    public MyStringFormatterKey (String variable, String  label, String dimension) : 
        this(String.IsNullOrEmpty(variable), String.IsNullOrEmpty(label), String.IsNullOrEmpty(dimension))
        {   } 

    public MyStringFormatterKey (Boolean isVariableAbsent, Boolean  isLabelAbsent, Boolean  isDimensionAbsent)
        {  this.isVariableAbsent = isVariableAbsent;  this.isLabelAbsent= isLabelAbsent; this.isDimensionAbsent = isDimensionAbsent; } 

    public override Int32 GetHashCode()
    {
        return 100 * (isVariableAbsent ? (0) : (1)) + 10 * (isLabelAbsent ? (0) : (1)) + (isDimensionAbsent ? (0) : (1));
    }

    public bool Equals(MyStringFormatterKey other)
    {
        return (this.GetHashCode() == other.GetHashCode());
    }
}

...


Dictionary<MyStringFormatterKey , Func<String, String, String, String>> formatterDictionary = 
    new Dictionary<MyStringFormatterKey , Func<String, String, String, String>>();

formatterDictionary.Add(new MyStringFormatterKey(false, true, false), 
    (variable, label, dimension) => String.Format("{0} [{1}]", variable, dimension));

...

Func<String, String, String, String> stringFormatter = formatterDictionary[new MyStringFormatterKey(variable, label, dimension)];

String result = stringFormatter(variable, label, dimension);

It could be made more generalized(I mean not just for 3 strings), but in the end such solution will be able to handle any possible combination or formatting idiosyncrasies.

Comments

-1
private String GetName(string variable, string label, string dimension)
{
    StringBuilder result = new StringBuilder();
    bool bEmpty = true;
    if (!String.IsNullOrEmpty(label)
    {
        result.Append(label);
        result.Append(' ');
    }
    if (!String.IsNullOrEmpty(dimension)
    {
        result.Append('[');
        result.Append(dimension);
        result.Append("] ");
    }
    if (!String.IsNullOrEmpty(variable)
    {
        result.Append('(');
        result.Append(dimension);
        result.Append(") ");
    }
    if (result.Count > 0)
    {
       result.Length := result.Length - 1;
    }
    return result.ToString();
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.