Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using generics to make an algorithm work on lists of "something" instead of only String's

Tags:

c#

generics

I have a small algorithm which replaces the position of characters in a String:

class Program
{
    static void Main(string[] args)
    {
        String pairSwitchedStr = pairSwitch("some short sentence");
        Console.WriteLine(pairSwitchedStr);

        Console.ReadKey();
    }

    private static String pairSwitch(String str)
    {
        StringBuilder pairSwitchedStringBuilder = new StringBuilder();
        for (int position = 0; position + 1 < str.Length; position += 2)
        {
            pairSwitchedStringBuilder.Append((char)str[position + 1]);
            pairSwitchedStringBuilder.Append((char)str[position]);
        }
        return pairSwitchedStringBuilder.ToString();
    }
}

I would like to make it as generic as possible, possibly using Generics. What I'd like to have is something which works with:

  • Anything that is built up using a list of instances.
  • Including strings, arrays, linked lists

I suspect that the solution must use generics as the algorithm is working on a list of instances of T (there T is ... something). Version of C# isn't of interest, I guess the solution will be nicer if features from C# version >2.0 is used.

I ended up with: (Where I fixed the error in the above code, it didn't handle odd lengths correctly)

    private static IEnumerable<T> switchSubstitutionCipher<T>(IEnumerable<T> input)
    {
        bool even = false;
        T lastItem = default(T);

        foreach (T element in input)
        {
            if (even) {
                yield return element;
                yield return lastItem;
            }

            even = !even;
            lastItem = element;
        }
        if (even)
            yield return lastItem;
    }
like image 312
Deleted Avatar asked Dec 03 '22 13:12

Deleted


1 Answers

Strings, in C#, are conceptually very different than an array or linked list. Although a string does implement IEnumerable<Char>, it is an immutable class, so you can't work with it like an IList<T> or Array.

I would recommend leaving your string implementation, then adding a generic implementation for any IList<T>:

private static IList<T> pairSwitch<T>(IList<T> original)
{
    List<T> results = new List<T>(original.Count);

    for (int i=0;i<original.Count-1;i+=2)  // Using -1 to make sure an odd number doesn't throw...
    {
        results.Add(original[i+1]);
        results.Add(original[i]);
    }
    return results;
}
like image 183
Reed Copsey Avatar answered May 25 '23 23:05

Reed Copsey