使用 Linq 修改字符串列表,仅保留最大 n 长度的字符串。

7
假设我们有一个字符串列表如下:
List<string> myList = new List<string>(){"one", "two", "three", "four"};

有一些长度超过3的项目。

借助Linq,我想将它们分成新的项目列表,因此新列表将包含这些项目:

{"one", "two", "thr", "ee", "fou", "r"};

不要问我为什么选择Linq。作为一名Linq粉丝,我不喜欢非Linq的代码:D


1
琐碎。你在一开始尝试了什么? - Ondrej Tucny
你很可能会更喜欢非LINQ代码,这些代码应该已经存在,但由于某种原因没有包含在帖子中...你对“仅使用LINQ”有什么要求吗?(即单个语句)? - Alexei Levenkov
我可以通过创建新列表和foreach循环来完成它。但我的问题是如何通过Linq来完成它。 - Aryan Firouzian
1
@MichaelMcGriff 如果列表中的项长度大于3,则将它们分成两个或更多项;如果长度小于3,则不做任何更改。 - Aryan Firouzian
2
我知道这是为了好玩,但请不要在现实世界中使用LINQ来做类似的事情。它并不适合这样的用途,所以与其他技术相比效率会非常低下。 - Nikki9696
显示剩余4条评论
3个回答

9

对于真正的代码基础,for 循环可能更好(即如其他答案所示)。

如果您确实需要使用 LINQ 将字符串分割成 3 个字母为一组,并将所有内容合并到 SelectMany 中:

var list = new[]{"", "a", "abc","dee","eff","aa","rewqs"};
var result = list
  .Select( 
    s => 
      Enumerable.Range(0, s.Length / 3 + 
             (s.Length == 0 || (s.Length % 3 > 0) ? 1 : 0))
      .Select(i => s.Substring(
         i * 3,
         Math.Min(s.Length - i * 3, 3))))
  .SelectMany(x=>x);

Range 创建一个可枚举的字符串片段(如果所有片段都是3个字符,那么长度为length/3,否则最后一个片段比3个字符短1个字符)。

.Select(i => s.Substring... 将字符串分成3个或更少字符的块(需要仔细调整长度以避免索引超出范围错误)。

.SelectMany 将3个字符片段的列表组合成平坦的3个字符片段列表。


注意: 此LINQ代码应用于娱乐/学习目的。如果您必须在生产代码中使用类似的LINQ解决方案,请至少将字符串拆分转换为更易读的辅助函数。


6
那既美丽又可怕。 - Michael McGriff
太棒了。谢谢你。 - Aryan Firouzian
@MichaelMcGriff,当然这远远不是最佳实践,但我相信它可以帮助在Linq中挑战。 - Aryan Firouzian
@MichaelMcGriff 完全同意“可怕”的部分 - 我在帖子中添加了一些关于它的评论。 OP 需要一个 LINQ 解决方案,所以我添加了一个至少可以解释的解决方案(还使用 "test".GroupBy((c,i)=> i/3) 将字符串拆分为 3 个字符段会更疯狂)。 - Alexei Levenkov

5

我不确定您可以使用Linq完成这项任务。以下是一种非Linq的解决方案:

for (int x = 0; x < myList.Count; x++)
{
    if (myList[x].Length > 3)
    {
        var oldString = myList[x];
        myList[x] = oldString.Substring(0, 3);
        myList.Insert(x + 1, oldString.Substring(3));
    }
}

编辑:显然你可以通过使用Linq完成这个任务。但是,这仍然是一个非Linq的解决方案...


2
仅仅因为你能做到,并不意味着你应该这么做 =) - Nikki9696

4

我看到我回答晚了,但我的答案基本上与被接受的答案相同。我主要发布它以展示查询语法解决方案,在这种情况下,我认为更易读。

var result =
    (from s in myList
     from i in Enumerable.Range(0, 1 + (s.Length - 1) / 3)
     let start = i * 3
     let length = Math.Min(3, s.Length - start)
     select s.Substring(start, length))
     .ToList();

好的替代语法。另外,你在我的帖子中刚修复的错误也出现了 - 空字符串被删除了。 - Alexei Levenkov
@AlexeiLevenkov 谢谢,我没注意到那个情况,已经修复了。 - Ivan Stoev

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接