Home > Software engineering >  C#: Generator at the end of a return statement
C#: Generator at the end of a return statement

Time:10-30

I have this working Python code which inverts the case of all characters of an input and returns the output:

return ''.join(letter.upper() if letter.islower() else (letter.lower() if letter.isupper() else letter) for letter in input())

In this line, the For loop is at the end of the line instead of line instead of it being before or on the line above it.

Would this be possible in C#? I've got a working version of the function below, where text1 is an input, but I can only condense it to 3 lines instead of 1:

string result = string.Empty;
foreach(char letter in text1) result  = Char.IsLower(letter) ? letter.ToString().ToUpper() : (Char.IsUpper(letter) ? letter.ToString().ToLower() : letter.ToString());
return result;

I thought it could be achieved by doing this:

return String.Join('', Char.IsLower(letter) ? letter.ToString().ToUpper() : (Char.IsUpper(letter) ? letter.ToString().ToLower() : letter.ToString()) foreach(char letter in text1));

But the syntax doesn't allow the foreach generator at the end.

I'm fairly new to C#, so I might be missing something obvious, but I can't find any refernce online about having a generator at the end of a statement like this.

CodePudding user response:

(something for x in iterable) in Python is a special comprehension syntax that can be used to create lists or generators based on an existing iterable. It is a special syntax that shares the keywords with a normal for loop but is not directly related to normal loops. The syntax is unique to Python and there is no direct replacement in C# for this.

The closest similar language construct in C# would be LINQ expressions which closely match the purpose that is often behind Python’s comprehensions. With a LINQ expression, you can start at with an enumerable (which is .NET’s iterable type) and then apply filters or mappings on top of that using the Where and Select LINQ methods.

So taking the following example in Python:

example = 'Foo Bar!'
result = ''.join(letter.upper() if letter.islower() else (letter.lower() if letter.isupper() else letter) for letter in example)
print(result) #fOO bAR!

A direct equivalent in C# using LINQ would look like this:

var example = "Foo Bar!";
var result = string.Join("", example.Select(letter =>
    char.IsLower(letter) ? char.ToUpper(letter) :
    char.IsUpper(letter) ? char.ToLower(letter) : letter
));
Console.WriteLine(result); // fOO bAR!

This works because a string is an enumerable of characters (IEnumerable<char>) and as such you can use the Select method to map each letter from the source to a new value.

  • Related