【问题标题】:Modify list of strings to only have max n-length strings (use of Linq)修改字符串列表以仅具有最大 n 长度的字符串(使用 Linq)
【发布时间】:2016-03-25 15:49:31
【问题描述】:

假设我们有如下字符串列表:

List<string> myList = new List<string>(){"one", "two", "three", "four"};

有些项目的长度超过3。

在Linq的帮助下,我想将它们划分为列表中的新项目,因此新列表将有这些项目:

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

不要问我为什么是 Linq。我是 Linq 粉丝,不喜欢 unLinq 代码:D

【问题讨论】:

  • 微不足道。 首先尝试了什么?
  • 您可能会更好地使用您应该拥有的非 LINQ 代码,但由于某种原因未包含在帖子中...您对“仅使用 LINQ”的要求是什么 - (即单个语句)?
  • 我可以通过创建新列表和 foreach 循环来做到这一点。但我的问题是 Linq 如何做到这一点。
  • @MichaelMcGriff 如果它们超过 3 个长度,则将它们分成两个或多个列表项,如果它们小于 3 个长度,则保持不变。
  • 我知道这是为了好玩,但请不要在现实世界中将 LINQ 用于类似的事情。这不是它的用途,因此与其他技术相比,它的效率非常低。

标签: c# string list linq


【解决方案1】:

我看到我在准备答案时迟到了,这与接受的基本相同,但我发布它主要是为了展示查询语法解决方案,在这种情况下IMO更具可读性

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();

【讨论】:

  • 很好的替代语法。顺便说一句,你有我刚刚在我的帖子中修复的相同错误 - 删除了空字符串。
  • @AlexeiLevenkov 谢谢,我没听清这个问题,已修复。
【解决方案2】:

对于真正的代码,基本for 可能会更好(即如other answer 所示。

如果您确实需要 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 个字符,则为长度/3,如果最后一个小于 3 个字符,则为长度/3)。

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

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


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

【讨论】:

  • 这既美丽又可怕。
  • 太棒了。谢谢。
  • @MichaelMcGriff,当然它甚至不接近最佳实践,但我相信它可以帮助在 Linq 中挑战。
  • @MichaelMcGriff 完全同意“可怕”的部分 - 我已经在帖子中内联了一些关于它的 cmets。 OP 需要一个 LINQ 解决方案,所以我添加了一个至少可以解释的解决方案(也使用 "test".GroupBy((c,i)=&gt; i/3) 将字符串拆分为 3 个字符段会更加疯狂)。
【解决方案3】:

我不确定您是否可以使用 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 解决方案......

【讨论】:

  • 仅仅因为你可以并不意味着你应该 =)
猜你喜欢
  • 1970-01-01
  • 2020-06-15
  • 1970-01-01
  • 2021-06-14
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 2013-12-14
相关资源
最近更新 更多