Next! Previous! Using the C# Remainder operator with Arrays



Jim Mc̮̑̑̑͒G
  ·  
27 November 2019  
  ·  
 4 min read

Have you ever had to write code for your app, that lets your users’ page back and forth between a list of items?

Typically, such code has:

  • an array of items
  • a variable which stores the “CurrentIndex”
  • two methods Next() and Previous(), which will most likely be called by UI buttons.

In those two methods, we invariably want to write code that prevents underflow and overflow of the index position. In more simple language, we never want to return index values that are:

  • smaller than zero.
  • greater than the index of the last item in the list.

In dealing with this scenario, you may have written code that looks something along the lines of the following; Here is a complete listing of a very simple .NET Core console application:-

using System;
using System.Collections.Generic;

namespace NextPrevious
{
    class Program
    {
        static void Main(string[] args)
        {
            var demo = new Demo();
            demo.RunDemo();
        }
    }

    class Demo
    {
        private List<int> pageIndices = new List<int> { 0, 1, 2, 3 };
        private int currentPageIndex = 0;

        private void Next()
        {
            if (currentPageIndex >= pageIndices.Count)
                return;

            currentPageIndex++;
        }

        private void Previous()
        {
            if (currentPageIndex < 0)
                return;
            
            currentPageIndex--;
        }

        public void RunDemo()
        {
            Console.WriteLine($"Starting Index is {currentPageIndex}");
            Next(); Next(); Next(); Next(); Next();Next();
            Console.WriteLine($"Current Index is {currentPageIndex}");
            Previous(); Previous(); Previous(); Previous(); Previous();Previous();
            Console.WriteLine($"Current Index is {currentPageIndex}");
        }
    }
}

Ok, simple stuff right? There are a handful of things to draw your attention to, in the above code listing:

  • We created a list with four items - the list is zero-indexed, as is usual.
  • We used a straightforward if statement to test the bounds of the range.
  • We called both Next() and Previous() more times, than there are available indices in the array, to demonstrate that our code doesn’t under or overflow the list.
  • Technically for code robustness, both methods should really also have included a test to ensure the array is not-null and that it has at least one item in the list - but I chose to skip this for brevity.




Enter stage, the C# Remainder Operator

I don’t pretend to be a particularly accomplished or refined coder. I’ve often found myself producing endless CRUD style applications that often don’t require much programming flair. Lack of practice means that I often don’t think of using some of the less commonly used C# operators.

I was recently looking at some sample code, produced by Microsoft in a GitHub repo. I stumbled upon something that I thought was a useful way of addressing a very common problem.

The example was using the % C# Remainder Operator. The purpose of the Remainder operator is to divide one number by another and to return the difference.

I’ve always understood that the C# % operator was called Modulo (with the output of the function being called “the Modulus”), but the current MS documentation calls it the Remainder operator.

I think that calling it “Remainder” makes its purpose clearer to non-mathematicians.

UPDATE: Props to my friend Philip Sutton who referred me in the direction of this article by Rob Connery : Mod and Remainder are not the same.

Typically, you’ll find this operator appearing in a loop, because it is commonly used as a way to describe “doing something every nth iteration”.

In the context of the code listing above, we can use the % remainder operator as a way to introduce some improvements:

  • shorten the amount of code we need to write down to one line.
  • provide functionality that effectively allows us to “wrap around to the other end of the list”, instead of simply stopping at either end.

I thought this was rather nice, so isolated out the example to share with you.

To use the code, simply replace the methods in the above code with the following:

private void Next()
{
    currentPageIndex = (currentPageIndex + 1) % (pageIndices.Count);
}

private void Previous()
{
    currentPageIndex = (currentPageIndex + pageIndices.Count-1) % pageIndices.Count;
}

To better understand what is going on, I would suggest putting some breakpoints in those methods and stepping through the code using the debugger. Notice how:

  • the index value wraps. Every time Next() is called, the index is increased … until you reach the last item in the list. When that happens, the code returns zero, effectively returning the index back to the beginning.
  • similarly, calling Previous() counts down the index values until we reach zero. The next invocation returns the highest index value, effectively sending us to the end of the list.

My only hesitation with adopting this code is that, unless you work with these less common C# operators on a frequent basis, it’s likely that the purpose of this code won’t be terribly obvious/legible.




Archives

2019 (27)