首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >字符串交换-大小写一行程序(6种方法)

字符串交换-大小写一行程序(6种方法)
EN

Code Review用户
提问于 2018-06-26 17:29:38
回答 2查看 719关注 0票数 2

我做了一个小项目,其中有六个一行匿名方法,可以交换任意长度的给定字符串的大小写。例如"heLLo,WOrlD“==> "HEllO,woRLd”。我使用这个字符串作为示例来演示每个函数是如何工作的。这个字符串"heLLo,woRLd“可以简单地用Console.ReadLine()替换,以获得用户预期的输入。我了解到一行程序是不可读的,也可能不是很好的实践,而且使用的变量名也不合适。整个项目都是为了好玩。我相信这样我能学到更多。我的期望是,有人能告诉我是否有更多的方法来做这个案子-交换(当然,必须是一条线)?我想我用了3种算法来做交换。此外,所有一行函数都是空函数,所有后续函数都比前面的函数短。

代码语言:javascript
复制
using System;
using System.Linq;

class x
{
    static void Main(string[] args)
    {
        // one-liner string swapcase
        (new Action<string>(delegate (string x) { foreach (char i in x) { char b = i; b^= char.IsLetter(b) ? (char)32 : (char)0; Console.Write(b); } }))("heLLo, woRLd");

        Console.WriteLine();

        //one-liner string swapcase2
        (new Action<string>(delegate (string x) { foreach (char i in x) { Console.Write(char.IsUpper(i) ? char.ToLower(i) : char.ToUpper(i)); } }))("heLLo, woRLd");

        Console.WriteLine();

        // one-liner string swapcase3
        ((Action<string>)(delegate (string x) { foreach (char i in x) { Console.Write(char.IsUpper(i) ? char.ToLower(i) : char.ToUpper(i)); } }))("heLLo, woRLd");

        Console.WriteLine();

        //one-liner string swapcase4
        ((Action<string>)((x) => { foreach (char i in x) { Console.Write(char.IsUpper(i) ? char.ToLower(i) : char.ToUpper(i)); } }))("heLLo, woRLd");

        Console.WriteLine();

        //one-liner string swapcase5
        "heLLo, woRLd".ToList().ForEach(i => Console.Write(char.IsUpper(i) ? char.ToLower(i) : char.ToUpper(i)));

        Console.WriteLine();
        //one-liner string swapcase6
        "heLLo, woRLd".ToList().ForEach(i => Console.Write(i^= char.IsLetter(i) ? (char)(1 << 5) : (char)0));
        Console.ReadLine();
    }
}
EN

回答 2

Code Review用户

发布于 2018-06-26 19:08:33

我觉得您的代码很有趣,但由于这不是代码高尔夫,而是代码评审,我将从我们的角度来回顾它,这是干净代码的第一步。

即使您试图编写紧凑的代码,也不应该使用神奇的注释和牺牲可读性。相反,将它们封装在(本地)函数中,或者使用适当的常量。您也不应该使用不相关的变量名,如这里,i用于char,而c则更合适。或者,您也可以使用Aggregate循环字符串并在StringBuilder中收集结果。(char)0可以用更漂亮的default代替。

代码语言:javascript
复制
const char caseOffset = (char)(1 << 5);

char SwapCase(char c) => c ^= (char.IsLetter(c) ? caseOffset : default);

var result = 
    "heLLo, woRLd"
        .Aggregate(
            new StringBuilder(), 
            (b, c) => b.Append(SwapCase(c))
        ).ToString();

另一种选择是使用Selectnew string,并向其提供新的结果。

代码语言:javascript
复制
var result = new string("heLLo, woRLd".Select(SwapCase).ToArray())

Select的优点是不再需要=> lambda了。

票数 9
EN

Code Review用户

发布于 2018-06-26 22:15:12

首先,我要感谢@t3chb0t给出了这样具体的反馈;感谢这个人,我有了更多的方法来交换上面提到的字符串。我张贴这是作为一个答案,因为没有其他任何实际的一行对我的问题。

代码语言:javascript
复制
//one-liner string swapcase7 ***idea from @t3chb0t***
Console.WriteLine(new string("heLLo, woRLd".Select(i => i^= char.IsLetter(i) ? (char)(1 << 5) : default).ToArray()));

//one-liner string swapcase8 ***idea from @t3chb0t***    
Console.WriteLine("heLLo, woRLd".Aggregate(new StringBuilder(), (b, o) => b.Append(((Func<char, char>)((a) => { a ^= char.IsLetter(a) ? (char)(1 << 5) : default; return a; }))(o))).ToString());

//one-liner string swapcase9 ***my own understanding of LINQ***
Console.WriteLine(new string((from i in "heLLo, woRLd" select ((Func<char, char>)((a) => { a ^= char.IsLetter(a) ? (char)(1 << 5) : default; return a; }))(i)).ToArray()));
票数 0
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/197295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档