LINQ lambda 表达式替换字符串中的多个字符?

发布于 2024-09-18 22:50:25 字数 273 浏览 10 评论 0原文

是否可以编写一个 lambda 表达式来迭代对象数组并替换其中一个属性中所有出现的“X”、“Y”、“ ”和“Z”?

例如

return query.Select(x => { x.SomePropertyName= x.SomePropertyName.Trim().Replace(' ', "_"); return x; }).ToList();

,由于某种原因,当我需要替换多个字符时,上面的查询不会替换单个字符。

谢谢

Is it possible to write a lambda expression that will iterate through array of objects and replace all occurences of 'X', 'Y', ' ' and 'Z' in one of the properties?

E.g.

return query.Select(x => { x.SomePropertyName= x.SomePropertyName.Trim().Replace(' ', "_"); return x; }).ToList();

For some reason, a query above doesn't replace a single character, when I need to replace multiple characters.

Thank you

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

夏见 2024-09-25 22:50:26

当我想用一个其他字符替换多个字符之一时,我经常使用 string.Split 和 string.Join 的组合:

char[] unwanted = new[] {'X', 'Y', 'Z'};
query = query.Select(x =>
{
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted));
    return x;
});

这将替换任何出现的 'X', 'Y''Z''_'。您可以将其与您选择的循环结构结合起来。

正如评论中所讨论的,在这种情况下使用 Select 并没有真正增加任何价值。普通的 foreach 循环就可以完成这项工作,甚至会生成更紧凑的代码:

char[] unwanted = new[] {'X', 'Y', 'Z'};
foreach(var x in query)
{
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted));
};

When I want to replace one of a number of characters with one single other character, I often use a combination of string.Split and string.Join:

char[] unwanted = new[] {'X', 'Y', 'Z'};
query = query.Select(x =>
{
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted));
    return x;
});

This will replace any occurrence of 'X', 'Y' or 'Z' with '_'. You can combine this with the looping construct of your choice.

As discussed in the comments, using Select does not really add any value in this case. A normal foreach loop would do the job, and would even produce more compact code:

char[] unwanted = new[] {'X', 'Y', 'Z'};
foreach(var x in query)
{
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted));
};
红尘作伴 2024-09-25 22:50:26

如果要使用 LINQ,可以使用 Select、ToArray 和 String(char[]) 构造函数,如下所示:

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty =
        new string(x.SomeProperty
                    .Select(c => (c == 'X' || ... || c == ' ') ? '_' : c)
                    .ToArray());
}

请注意,LINQ 并不是用于产生副作用,而是用于从现有枚举创建新的枚举。所以这里使用 foreach 循环更好。


但为什么不只是一系列 Replace 调用呢?

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty = x.SomeProperty
                      .Replace('X', '_')
                      .Replace('Y', '_')
                      .Replace('Z', '_')
                      .Replace(' ', '_');
}

或者您是否试图用一系列字符替换单个字符?
然后使用带有两个字符串的 String.Replace 重载:

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty = x.SomeProperty.Replace(" ", "ABC");
}

If you want to use LINQ, you can use Select, ToArray and the String(char[]) constructor like this:

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty =
        new string(x.SomeProperty
                    .Select(c => (c == 'X' || ... || c == ' ') ? '_' : c)
                    .ToArray());
}

Note that LINQ is not intended to be used to cause side-effects, but to create new enumerables from existing enumerables. So a foreach loop is better here.


But why not simply a chain of Replace calls?

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty = x.SomeProperty
                      .Replace('X', '_')
                      .Replace('Y', '_')
                      .Replace('Z', '_')
                      .Replace(' ', '_');
}

Or are you trying to replace a single character with a sequence of characters?
Then use the String.Replace overload that takes two strings:

var result = query.ToList();
foreach (var x in result)
{
    x.SomeProperty = x.SomeProperty.Replace(" ", "ABC");
}
岛歌少女 2024-09-25 22:50:26

如果您想使用正则表达式,可以执行以下操作:

query.Select(
    x => { 
        x.SomePropertyName = Regex.Replace(x.SomePropertyName, @"[XYZ\s]", "_"); 
        return x; })

If you're in the mood to use a regular expressions, you can do something like this:

query.Select(
    x => { 
        x.SomePropertyName = Regex.Replace(x.SomePropertyName, @"[XYZ\s]", "_"); 
        return x; })
西瑶 2024-09-25 22:50:26

尽管您请求了 LINQ,但这种(滥用)使用 LINQ 会带来副作用,并使代码变得混乱。与对象数组一起使用的另一种方法是使用 Array.ForEach方法

// using Fredrik Mörk's approach
Array.ForEach(query, x =>
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)));

// using Regex
Array.ForEach(query, x => x.SomePropertyName =
    Regex.Replace(x.SomePropertyName, "[XYZ]", "_", RegexOptions.IgnoreCase));

当然使用正则表达式需要一些知识。请注意使用在正则表达式中具有特殊含义的元字符。您可以使用 正则表达式来清理字符。转义方法

Although you requested LINQ, this (ab)use of LINQ relies on side-effects and clutters the code. An alternative to use with an array of objects (which you stated is the case in your question) is to use the Array.ForEach method:

// using Fredrik Mörk's approach
Array.ForEach(query, x =>
    x.SomePropertyName = string.Join("_", x.SomePropertyName.Split(unwanted)));

// using Regex
Array.ForEach(query, x => x.SomePropertyName =
    Regex.Replace(x.SomePropertyName, "[XYZ]", "_", RegexOptions.IgnoreCase));

Of course use of regex requires some knowledge. Be mindful of using metacharacters that hold a special meaning in regex. You can sanitize your characters by using the Regex.Escape method.

寄人书 2024-09-25 22:50:26

循环遍历字符串中的每个字符,并在必要时替换它。

 var xyz = new HashSet<char>(new[] { 'X', 'Y', 'Z' });
 char replacement = '_';
 var results = query
  .Select(x =>
     {
      var value = x.SomePropertyName
     .Trim()
     .Select(y => xyz.Contains(y) ? replacement : y)
     .ToArray();
      x.SomePropertyName = new string(value);
      return x;
     })
  .ToList();

loop through each character in the string and replace it if necessary.

 var xyz = new HashSet<char>(new[] { 'X', 'Y', 'Z' });
 char replacement = '_';
 var results = query
  .Select(x =>
     {
      var value = x.SomePropertyName
     .Trim()
     .Select(y => xyz.Contains(y) ? replacement : y)
     .ToArray();
      x.SomePropertyName = new string(value);
      return x;
     })
  .ToList();
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文