C# 林克郡拉姆达。。。。改进此方法
我正在学习更多关于LINQ和Lambda表达式的知识,但在这个阶段,我只是不“获取”Lambda表达式 是的。。。我是这些新概念的新手 我的意思是,我看到的每个例子都说明了如何对参数进行加减 那更复杂一点的呢 为了帮助我更好地理解,我发布了一个小挑战,供希望参与的人使用。我有下面的方法,它将接受任何字符串,并将在任何大写字符和它们前面的相邻字符之间放置空格(如下所示) i、 e.C# 林克郡拉姆达。。。。改进此方法,c#,linq,lambda,C#,Linq,Lambda,我正在学习更多关于LINQ和Lambda表达式的知识,但在这个阶段,我只是不“获取”Lambda表达式 是的。。。我是这些新概念的新手 我的意思是,我看到的每个例子都说明了如何对参数进行加减 那更复杂一点的呢 为了帮助我更好地理解,我发布了一个小挑战,供希望参与的人使用。我有下面的方法,它将接受任何字符串,并将在任何大写字符和它们前面的相邻字符之间放置空格(如下所示) i、 e. “样本文本”=“样本文本” “DoesNotMatterHowManyWords”=“不管有多少个单词” 这是代码
“样本文本”=“样本文本”
“DoesNotMatterHowManyWords”=“不管有多少个单词” 这是代码
public static string ProperSpace(string text)
{
var sb = new StringBuilder();
var lowered = text.ToLower();
for (var i = 0; i < text.Length; i++)
{
var a = text.Substring(i, 1);
var b = lowered.Substring(i, 1);
if (a != b) sb.Append(" ");
sb.Append(a);
}
return sb.ToString().Trim();
}
我也很欣赏其他(类似)主题的链接
尤其是这是如此真实 就我个人而言,我认为您的方法简单明了,我会坚持使用它(我认为我甚至可能在某些地方编写了完全相同的代码) 更新: 这个作为起点怎么样
public IEnumerable<char> MakeNice(IEnumerable<char> str)
{
foreach (var chr in str)
{
if (char.ToUpper(chr) == chr)
{
yield return ' ';
}
yield return chr;
}
}
public string MakeNiceString(string str)
{
return new string(MakeNice(str)).Trim();
}
public IEnumerable MakeNice(IEnumerable str)
{
foreach(str中的var chr)
{
if(char.ToUpper(chr)=chr)
{
收益率‘;
}
收益率;
}
}
公共字符串(字符串str)
{
返回新字符串(MakeNice(str)).Trim();
}
对于这种情况,我会使用正则表达式
public static string ProperSpace(string text)
{
var expression = new Regex("[A-Z]");
return expression.Replace(text, " $0");
}
如果要使用lambda,可以使用:
public static string ManipulateString(string text, Func<string, string> manipulator)
{
return manipulator(text);
}
// then
var expression = new Regex("[A-Z]");
ManipulateString("DoesNotMatterHowManyWords", s => expression.Replace(text, " $0"));
像莱皮一样,我不确定这是否是林克的好候选人。当然,你可以强迫它,但这不是一个有用的例子。一个小的调整是将
text[i]
与lowered[i]
进行比较,以避免一些不必要的字符串-可能会将sb默认为new StringBuilder(text.Length)
(或更高的一小部分):
除此之外,我不会去管它 以下是一种方法:
string.Join("", text.Select((c, i) => (i > 0 && char.IsUpper(c)) ? " " + c : c.ToString()).ToArray());
但我看不出有什么改进。看看这个
编辑:对于那些想知道的人:是的,我故意选择了一个丑陋的解决方案。我很好奇为什么简单的正则表达式替换是不够的。我为其他人写了一篇文章,就是这样:
"[AI](?![A-Z]{2,})[a-z]*|[A-Z][a-z]+|[A-Z]{2,}(?=[A-Z]|$)"
我已经在这里的另一个公告板上发布了此消息:。有一个bug需要一个post-regex trim,我还没有机会解决它,但是也许其他人可以发布一个修复程序
使用替换模式:“$0[space]”将[space]替换为实际的空格,这将大大减少代码量
它处理一些特殊情况,这些情况可能超出了您尝试执行的范围,但公告栏线程将为您提供这些情况的信息
编辑:p.S.开始学习LINQ的一些应用程序的一个好方法是查看和标签,并查找C#post。LINQ对对象有许多不同且更复杂的用途,这将帮助您识别该技术的一些更有用(?)和更有趣的应用。有关LINQ的有用性(如果您需要说服力),您可以查看问题
我认为第一步是习惯点语法,然后再转到“sql”语法。否则,一开始它只会伤害你的眼睛。我确实想知道微软是否没有通过推行sql语法来减缓linq的普及,这让很多人觉得“恶心,我的C#中的DB代码”
至于lambdas,首先尝试使用匿名委托编写一些代码,因为如果您没有这样做,您将无法真正理解这是怎么回事。我有一个正则表达式解决方案,它只比您当前的循环[1]慢8倍,而且比您的解决方案[2]更难阅读
public static string ProperSpace(string text)
{
return text.Aggregate(new StringBuilder(), (sb, c) =>
{
if (Char.IsUpper(c) && sb.Length > 0)
sb.Append(" ");
sb.Append(c);
return sb;
}).ToString();
}
return Regex.Replace(text, @"(\P{Lu})(\p{Lu})", "$1 $2");
它匹配unicode字符组,在本例中为非大写,后跟大写,然后在它们之间添加空格。此解决方案比其他只查找[A-Z]的基于正则表达式的解决方案效果更好
[1] 有保留地说,我快速编写的测试可能会很糟糕。[2] 有人不通过谷歌搜索就知道unicode字符组吗?;) 您可以使用现有的LINQ函数来实现这一点,但这可能不是最好的方法。下面的LINQ表达式可以工作,但并不有效,因为它会生成大量额外的字符串
public static string ProperCase(string text)
{
return text.Aggregate(
string.Empty,
(acc, c) => Char.ToLower(c) != c ? acc + " " + c.ToString() : acc + c.ToString())
.Trim();
}
这样做与原始代码相同,甚至可以避免生成第二个(小写)字符串
你有没有想过使用聚合函数 例如,假设我有一个名为routes的数组,我想将所有活动字段设置为false。这可以通过以下方式完成: routes.Aggregate(false,(值,route)=>route.Active=false); -Routes是表的名称。 -第一个false只是种子值,需要与正在设置的值的类型相同。这有点…多余。 -值也是冗余的,基本上是第一个值。 -route是聚合值(序列中的每个单独元素) 不再有多余的foreach循环…
我也不太懂Lambda的表情。。。但我肯定有q genius在某个地方可以利用这个来做那个…谢谢leppie。。。我只是希望能够使用这种方法来看看LINQ或Lambda如何改进它。这个练习将帮助我掌握这些新概念。。。请继续关注人们的想法。该代码将添加一个前导空格字符,而不会返回字符串。有机会更新吗?为字符串更新(认为这是显而易见的;p)@本约尔,我的更好,没有副作用!:)抱歉,但我不明白为什么这个(或原来的)解决方案会比下面的LINQ One Liners更简单或性能更好……下面没有LINQ One Liners:)呵呵。由于一个事实,这更容易理解。没有副作用:)不确定你的regexp在那里,([a-z]+)([a-z]+)->$1$2对我有用。我使用regex的问题是它们非常加密
public static string ProperSpace(string text)
{
return text.Aggregate(new StringBuilder(), (sb, c) =>
{
if (Char.IsUpper(c) && sb.Length > 0)
sb.Append(" ");
sb.Append(c);
return sb;
}).ToString();
}
return Regex.Replace(text, @"(\P{Lu})(\p{Lu})", "$1 $2");
public static string ProperCase(string text)
{
return text.Aggregate(
string.Empty,
(acc, c) => Char.ToLower(c) != c ? acc + " " + c.ToString() : acc + c.ToString())
.Trim();
}
var result = text.Aggregate(new StringBuilder(),
(sb, c) => (Char.IsUpper(c) ? sb.Append(' ') : sb).Append(c));