Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing if else statement with any design pattern or better approach

This code doesn't look clean and this if condition can grow

public int VisitMonth(int months)
    {
        int visit = 0;

        if (months <= 1)
        {
            visit = 1;
        }
        else if (months <= 2)
        {
            visit = 2;
        }
        else if (months <= 4)
        {
            visit = 3;
        }
        else if (months <= 6)
        {
            visit = 4;
        }
        else if (months <= 9)
        {
            visit = 5;
        }
        else if (months <= 12)
        {
            visit = 6;
        }
        else if (months <= 15)
        {
            visit = 7;
        }
        else if (months <= 18)
        {
            visit = 8;
        }
        else if (months <= 24)
        {
            visit = 9;
        }
        else if (months <= 30)
        {
            visit = 10;
        }
        else if (months <= 36)
        {
            visit = 11;
        }
        else if (months <= 48)
        {
            visit = 12;
        }
        else if (months <= 60)
        {
            visit = 13;
        }
        else
        {
            visit = 14;
        }
        return visit;
    }

Is there any better solution to this problem? Sadly that function isn't linear so it's not easy to code that in a mathematical way.

like image 877
user6392608 Avatar asked Jan 30 '19 15:01

user6392608


People also ask

What is the replacement of if-else statement?

The Ternary Operator One of my favourite alternatives to if...else is the ternary operator. Here expressionIfTrue will be evaluated if condition evaluates to true ; otherwise expressionIfFalse will be evaluated. The beauty of ternary operators is they can be used on the right-hand side of an assignment.

How can we avoid multiple if-else using design patterns in Java?

Create an abstract base state class. Implement each state as a separate class inheriting from base state. Let the Booking ` class have a private or internal method that takes the state base class as a parameter.


Video Answer


2 Answers

Should be more suitable to be reused :You can write a "Interval" Class with "inRange" methode like this :

 public struct Interval<T>
       where T : IComparable
{
    public T Start { get; set; }
    public T End { get; set; }
    public T Visit { get; set; }

    public Interval(T visit, T start, T end)
    {
        Visit = visit;
        Start = start;
        End = end;
    }

    public bool InRange(T value)
    {
      return ((!Start.HasValue || value.CompareTo(Start.Value) > 0) &&
          (!End.HasValue || End.Value.CompareTo(value) >= 0));
    }
}

And then use like this :

public static readonly List<Interval<int>> range = new List<Interval<int>>
        {
                new Interval<int>(1, 0, 1),
                new Interval<int>(2, 1, 2),
                new Interval<int>(3, 2, 4),
                new Interval<int>(4, 4, 6),
                new Interval<int>(5, 6, 9),
                new Interval<int>(6, 9, 12),
                new Interval<int>(7, 12, 15),
                new Interval<int>(8, 15, 18),
                new Interval<int>(9, 18, 24),
                new Interval<int>(10, 24, 30),
                new Interval<int>(11, 30, 36),
                new Interval<int>(12, 36, 48),
                new Interval<int>(13, 48, 60),
                new Interval<int>(14, 60, int.MaxValue)
        };

var months = 5;
var visit = range.Where(x => x.InRange(months)).Select(x => x.Visit).FirstOrDefault();
like image 158
Beedjees Avatar answered Oct 31 '22 21:10

Beedjees


Possibly in C# 8 (this feature is not official yet, but works in recent IDEs if you turn it on):

int months = ...;
int visit = months switch
{
    int j when j <= 1 => 1,
    int j when j <= 2 => 2,
    int j when j <= 4 => 3,
    int j when j <= 6 => 4,
    int j when j <= 9 => 5,
    // ...
    _ => 42 // default
};

You can do similar in earlier C#, since this is a method:

public int VisitMonth(int months)
{
    switch (months)
    {
        case int j when j <= 1: return 1;
        case int j when j <= 2: return 2;
        case int j when j <= 4: return 3;
        // etc
        default: return 14;
    }
}
like image 34
Marc Gravell Avatar answered Oct 31 '22 23:10

Marc Gravell