tags:

views:

561

answers:

9

I want to iterate over the alphabet like so:

foreach(char c in alphabet)
{
 //do something with letter
}

Is an array of chars the best way to do this? (feels hacky)

Edit: The metric is "least typing to implement whilst still being readable and robust"

+31  A: 

(Assumes ASCII, etc)

for (char c = 'A'; c <= 'Z'; c++)
{
    //do something with letter 
} 

Alternatively, you could split it out to a provider and use an iterator (if you're planning on supporting internationalisation):

public class EnglishAlphabetProvider : IAlphabetProvider
{
    public IEnumerable<char> GetAlphabet()
    {
        for (char c = 'A'; c <= 'Z'; c++)
        {
            yield return c;
        } 
    }
}

IAlphabetProvider provider = new EnglishAlphabetProvider();

foreach (char c in provider.GetAlphabet())
{
    //do something with letter 
} 
Richard Szalay
Woah...never thought of that. Brilliant!
Bobby
If you neeeeed foreach: `Enumerable.Range('a', 'z'-'a' + 1).Select(x=>(char)x)`
Rob Fonseca-Ensor
@Richard: You just give half of the solution. I like your generic IAlphabetProvider approach, but you need a factory to get the correct provider. Something like:var provider = AlphabetProvider.GetProvider(CultureInfo.CurrentCulture);
Steven
It's just sample code, I can't write the entire application in my answer. FYI by having a static method, your solution is coupled to the AlphabetProvider class.
Richard Szalay
@Rob - you can replace that Select with `Cast<char>`.
Daniel Earwicker
roosteronacid
@earwicker have you actually tried that?
Rob Fonseca-Ensor
@Rob - argh! I forgot that normal casts don't work between generic parameters. If you write your own version of `Cast`, you find the compiler won't accept it unless you cast to `object` first. Which makes it a boxing conversion, so you can only get out exactly whatever you put in. So I withdraw my comment.
Daniel Earwicker
(Although I think it will work in C# 4.0, just installing it now to find out.)
Daniel Earwicker
Results are mixed... a generic cast via `dynamic` will work. But `Enumerable.Cast` still does an old-style unboxing, so no change there. But it is very easy to write a similar `DynamicCast` extension that says `yield return (TOut)(dynamic)item`, and that works.
Daniel Earwicker
+1  A: 

You could do this:

for(int i = 65; i <= 95; i++)
{
    //use System.Convert.ToChar() f.e. here
    doSomethingWithTheChar(Convert.ToChar(i));
}

Though, not the best way either. Maybe we could help better if we would know the reason for this.

Bobby
Agreed, need reason.
NickLarsen
Needs more `char`!
meagar
+1  A: 

Well to use the foreach loop in C#, alphabet can be any IEnumerable<char>. What feels "hacky" about it?

NickLarsen
+11  A: 

Or you could do,

string alphabet = "abcdefghijklmnopqrstuvwxyz";

foreach(char c in alphabet)
{
 //do something with letter
}
Colin Newell
With this solution, internationalization is easy: use different letters :) (assuming C#'s foreach char goes by letter rather than 8-bit sequence). If it doesn't, I don't know the best approach for multi-byte characters in C#.
Joey Adams
A: 

I found this:

foreach(char letter in Enumerable.Range(65, 26).ToList().ConvertAll(delegate(int value) { return (char)value; }))
{
//breakpoint here to confirm
}

while randomly reading this blog, and thought it was an interesting way to accomplish the task.

Chris
A: 
Enumerable.Range(65, 26).Select(a => new { A = (char)(a) }).ToList().ForEach(c => Console.WriteLine(c.A));
John Boker
Not much point newing-up an anonymous object to store a single property. And the built-in `foreach` statement is usually clearer for performing an action on each item of a sequence - that's what it's for.
Daniel Earwicker
A: 

Reading through the "solution" a few above which had been proposed by "a blog" got me frightened for the future of humanity. About to go on a "... and that's why I hate blogs" rant, I figured I should take a look at the offending blog itself before ripping into it. It's a good think I checked, because as it turns out it is the reader who posted the solution into this thread who should be sent to Siberia, not the blog author, because the title of the article from which that "solution" was taken is "A Quick Lesson in Overengineering".

If this was a thread about "fun solutions", "goofy solutions", or just "who can make the most unusual sandwich" alarm bells wouldn't be sounding, but if most of the people on this thread think these are good solutions perhaps it is time to make the tent a little bit smaller. Right now, anyone who has read this far is thinking it might be time for me to loosen my tie a smidge, but not so fast.

I see "solutions" like this crap find their way into production code, too often. Code that looks like it was the winner in an Obfuscation Contest, code that throws off objects like its the Octomom. This is not what code should be.

Code has two purposes, and only two purposes: Purpose 1: Communicate with other people. Purpose 2: Communicate with a machine. Anything else that code "should do" either fits into one of those categories, or it isn't valid.

If you go back through the various solutions proposed to this intense overwhelmingly difficult problem (iterating over the alphabet) you should immediately realize that all but two of the solutions are crap. Now, don't get me wrong, that doesn't mean the other two solutions are any good; that all depends.

The two "good" solutions may also be crap, depending on the real problem. If the problem is to iterate over an "arbitrary" alphabet in the natural order for that alphabet, then none of these solutions come at all close, and this is why you should be gathering your children together and getting read for the coming apocolypse.

Instead of asking "what do you mean -- exactly" of the original poster, everyone starts throwing bizarre solutions to a problem that is either underspecified, or is so maddeningly simple that it doesn't deserve a thread of its own, much less the collection of motly drug induced solutions that it inspired.

You're all fired.

Donald Trump
A: 

Now I finished reading the "overengineering" blog entry that got quoted in this article, the solution I defended as being out of context. Having read the blog post in its entirety, I can now post that said blog author is also fired, as his "simple" solution is also wrong.

Now, you may be asking yourself (as I did just a second ago) "Hey, why doesn't smug boy there, who keeps firing everyone post his OWN solution". Good question (if I may say so myself). The answer is "BECAUSE I DON'T KNOW WHAT THE FRIGGIN' PROBLEM IS!" so how can I post a solution.

Is order important? Which order? Dictionary order? Is this English only? What about upper and lower case?

Now, if the problem is to iterate over one case only, in the English alphabet, there is no need for another post of the "right" solution, because it already appeared. (Scroll up to the "Enumerable.Range" solution). If it is anything else (as it would probably be in the real world) then we would need to find out the real problem before solving it.

This thread is just an embarassment to software. I'm ashamed. It is as if someone said "Hey! How do I install a light bulb" on people with no humor intended started postings like "First you need to get three ladders and 17 people ...". Hopefully most of the postings were from hobbyists.

Donald Trump