I have the following code which I would like to see as a oneliner. However, since I am very new to C#, I currently have no clue on how to do this...
Code:
static string ROT13 (string input)
{
if (string.IsNullOrEmpty(input)) return input;
char[] buffer = new char[input.Length];
for (int i = 0; i < input.Length; i++)
{
char c = input[i];
if (c >= 97 && c <= 122)
{
int j = c + 13;
if (j > 122) j -= 26;
buffer[i] = (char)j;
}
else if (c >= 65 && c <= 90)
{
int j = c + 13;
if (j > 90) j -= 26;
buffer[i] = (char)j;
}
else
{
buffer[i] = (char)c;
}
}
return new string(buffer);
}
I am sorry for any inconvenience, just trying to learn more about this pretty language :)
What about this? I just happen to have this code lying around, it isn't pretty, but it does the job. Just to make sure: One liners are fun, but they usually do not improve readability and code maintainability... So I'd stick to your own solution :)
static string ROT13(string input)
{
return !string.IsNullOrEmpty(input) ? new string (input.ToCharArray().Select(s => { return (char)(( s >= 97 && s <= 122 ) ? ( (s + 13 > 122 ) ? s - 13 : s + 13) : ( s >= 65 && s <= 90 ? (s + 13 > 90 ? s - 13 : s + 13) : s )); }).ToArray() ) : input;
}
If you need more clarification, just ask.
Just an alternative version that uses other chars in the comparison to make things more "clear"
static string ROT13(string input)
{
return !string.IsNullOrEmpty(input) ? new string(input.Select(x => (x >= 'a' && x <= 'z') ? (char)((x - 'a' + 13) % 26 + 'a') : ((x >= 'A' && x <= 'Z') ? (char)((x - 'A' + 13) % 26 + 'A') : x)).ToArray()) : input;
}
Not really a one liner but still shorter than your original code and more understandable than the other answer:
static string Rot13(string input)
{
if(input == null)
return null;
Tuple<int, int>[] ranges = { Tuple.Create(65, 90), Tuple.Create(97, 122) };
var chars = input.Select(x =>
{
var range = ranges.SingleOrDefault(y => x >= y.Item1 && x <= y.Item2);
if(range == null)
return x;
return (char)((x - range.Item1 + 13) % 26) + range.Item1;
});
return string.Concat(chars);
}
Another version that even better expresses what happens in ROT13 is this:
static string Rot13(string input)
{
var lowerCase = Enumerable.Range('a', 26).Select(x => (char)x).ToArray();
var upperCase = Enumerable.Range('A', 26).Select(x => (char)x).ToArray();
var mapItems = new[]
{
lowerCase.Zip(lowerCase.Skip(13).Concat(lowerCase.Take(13)), (k, v) => Tuple.Create(k, v)),
upperCase.Zip(upperCase.Skip(13).Concat(upperCase.Take(13)), (k, v) => Tuple.Create(k, v))
};
var map = mapItems.SelectMany(x => x).ToDictionary(x => x.Item1, x => x.Item2);
return new string(input.Select(x => Map(map, x)).ToArray());
}
static char Map(Dictionary<char, char> map, char c)
{
char result;
if(!map.TryGetValue(c, out result))
return c;
return result;
}
One more an alternative version:
static string ROT13(string input)
{
String.Join("", input.Select(x => char.IsLetter(x) ? (x >= 65 && x <= 77) || (x >= 97 && x <= 109) ? (char)(x + 13) : (char)(x - 13) : x))
}
来源:https://stackoverflow.com/questions/18739091/is-it-possible-to-write-a-rot13-in-one-line