Click here to Skip to main content
15,886,788 members
Articles / Programming Languages / C# 5.0
Tip/Trick

Modular IEnumerable Extensions

Rate me:
Please Sign up or sign in to vote.
4.75/5 (4 votes)
8 Apr 2014CPOL 14.5K   5   8
This tip describes an IEnumerable extension method that allows you to select an item modulo Count()

Introduction

This tip describes an IEnumerable extension method that allows you to select an item at its index modulo Count().

Using the Code

Given an object enumerable that implements IEnumerable<T>, you can use the following extension method ElementAtModCount to select an item from this object in the sense that:

C#
enumerable.ElementAtModCount(i) = enumerable.ElementAtModCount(i mod Count)  

This extension method is given as follows:

C#
using System.Collections.Generic;
using System.Linq;

namespace CodeProject.Articles.EnumerableExtensions
{
    public static class EnumerableExtensions
    {
        /// <summary>
        /// Returns the element of an object that implements
        /// IEnumerable at the index modulo the total number of 
        /// elements in that object.
        /// </summary>
        /// <typeparam name="T">Type T</typeparam>
        /// <param name="enumerable">An IEnumerable</param>
        /// <param name="index">The index of the item to get</param>
        /// <returns></returns>
        public static T ElementAtModCount<T>(this IEnumerable<T> enumerable, int index)
        {
            // In general, an object implementing IEnumerable does not have the 
            // Count property (O(1)), so it is expensive to call .Count() (O(n)). 
            // So we set it here, just in case...     
            var count = enumerable.Count();

            var indexModCount = ((index % count) + count) % count;

            // Again, in general this is quite expensive (O(n)). But
            // like above, if an object implements IEnumerable, and has the [] indexer
            // then this is O(1)
            return enumerable.ElementAt(indexModCount);
        }

    }
}

An example of how to use this is given as follows:

C#
using CodeProject.Articles.EnumerableExtensions;
using System;
using System.Collections.Generic;

namespace CodeProject
{
    class Program
    {
        static void Main(string[] args)
        {
            var list =
                new List<string>() 
                { "Monday", "Tuesday", "Wednesday", "Thursday", 
                  "Friday", "Saturday", "Sunday" };

            // The answer's Tuesday
            Console.WriteLine(string.Format(
                "It is Monday today, and in 365 days it will be {0}",
                list.ElementAtModCount(365)));

            // The answer's Friday
            Console.WriteLine(string.Format(
               "It is Monday today, and three days ago it was {0}",
               list.ElementAtModCount(-3)));

            Console.ReadLine();
        }
    }
} 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
QuestionWhy would this be useful? Pin
JV99999-Apr-14 5:04
professionalJV99999-Apr-14 5:04 
AnswerRe: Why would this be useful? Pin
LShep9-Apr-14 7:06
LShep9-Apr-14 7:06 
GeneralMy vote of 5 Pin
Christian Amado9-Apr-14 2:20
professionalChristian Amado9-Apr-14 2:20 
GeneralMy vote of 5 Pin
Volynsky Alex8-Apr-14 22:10
professionalVolynsky Alex8-Apr-14 22:10 
QuestionMaths Pin
phil.o8-Apr-14 21:29
professionalphil.o8-Apr-14 21:29 
AnswerRe: Maths Pin
LShep9-Apr-14 0:38
LShep9-Apr-14 0:38 
GeneralRe: Maths Pin
phil.o9-Apr-14 3:59
professionalphil.o9-Apr-14 3:59 
AnswerRe: Maths Pin
George Swan9-Apr-14 20:47
mveGeorge Swan9-Apr-14 20:47 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.