HiveBrain v1.2.0
Get Started
← Back to all entries
patterncsharpMinor

Uppercase the initial char of every string in a list

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
theuppercasechareveryinitialliststring

Problem

My problem is that I have a sequence, potentially infinite, of strings. Let's suppose it to be

{"Mickey Mouse", "Bugs Bunny", "Winnie the Pooh"}


I have to make an exthension-method Initials that returns a sequence of their capital letters in uppercase, so in this case, doing:

var names = new string [] {"Mickey  Mouse", "Bugs    Bunny", "Winnie  the Pooh"}
foreach (var cl in names . Initials ())
Console.WriteLine(cl);


returns, in order, MM, BB, WTP. Note that whitespaces have not to be considered.

After hours of staring at the screen, i managed to write this not so goodlooking code:

public static IEnumerable Initials(this IEnumerable names)
{
    var res = new List();
    var  listOfArrayOfStrings = names.Select(s => s.Split());
    foreach (var arrayOfStrings in listOfArrayOfStrings)
    {
        string newString = "";
        foreach (var singleString in arrayOfStrings)
        {
            if (!string.IsNullOrWhiteSpace(singleString)) //no whitespaces
            {
                var temp =  char.ToUpper(singleString[0]).ToString();       //first upper String
                newString += temp;
            }
        }
        res.Add(newString);
    }
    return res;
}


Then, my disliked R# suggested me to do some refacory and then it became the following:

var  listOfArrayOfStrings = names.Select(s => s.Split());
            return listOfArrayOfStrings.Select(arrayOfStrings => 
                (from singleString in arrayOfStrings 
                 where !string.IsNullOrWhiteSpace(singleString) 
                 select char.ToUpper(singleString[0]).ToString())
                 .Aggregate("", (current, temp) => current + temp))
                 .ToList();


Now, I have two questions about this:

-
Is this, in your opinion, a good way to reach my aim?

-
I will have to do a written test where I'll have to do something like that. How can I "guess" something like that without R#? I mean, I'm still having difficulties underst

Solution

Start by writing a method that returns the initials of a single string.

private static string GetInitials(string name)
{
    ???
}


You have the right idea, but there are some overloads we can use that will make the code a bit nicer:

private static string GetInitials(string name)
{
    var initials = name
        .Split((char[])null, StringSplitOptions.RemoveEmptyEntries)
        .Select(w => char.ToUpper(w[0]));
    return new string(initials.ToArray());
}


Here we've used the overload of Split that won't return empty entries, so we don't have to check for empty entries. We've also used the string(char[]) constructor instead of building up the string ourselves.

Now Initials we be written as

return names.Select(GetInitials);


There's a problem with both versions in that the method will not return if the input sequence is infinite (which you've mentioned is a case you want to handle).

Suppose we have this helper method to create an infinite sequence of a single value

private static IEnumerable Repeat(T value)
{
    while (true)
    {
        yield return value;
    }
}


Then our method should be able to handle this client code:

foreach (var cl in Repeat("Mickey Mouse").Initials().Take(5))
{
    Console.WriteLine(cl);
}


The versions posted must process every element of the sequence before they return, which isn't possible for infinite sequences.

Code Snippets

private static string GetInitials(string name)
{
    ???
}
private static string GetInitials(string name)
{
    var initials = name
        .Split((char[])null, StringSplitOptions.RemoveEmptyEntries)
        .Select(w => char.ToUpper(w[0]));
    return new string(initials.ToArray());
}
return names.Select(GetInitials);
private static IEnumerable<T> Repeat<T>(T value)
{
    while (true)
    {
        yield return value;
    }
}
foreach (var cl in Repeat("Mickey Mouse").Initials().Take(5))
{
    Console.WriteLine(cl);
}

Context

StackExchange Code Review Q#77929, answer score: 4

Revisions (0)

No revisions yet.