【问题标题】:Replace contiguous duplicates by a set value, but only if length of contiguous range more than a threshold用设定值替换连续重复,但前提是连续范围的长度超过阈值
【发布时间】:2019-11-06 18:10:57
【问题描述】:

将列表元素中的连续相同值替换为另一个给定值的有效方法是什么,但前提是连续序列运行超过一定数量的元素(例如:大于或等于 5)

例子:

[“红色”; “红色的”; “蓝色”; “绿色”; “绿色”; “红色”; “红色的” ; “红色的”; “红色的”; “红色的”; "红色"; "黄色"; “白色的”; “白色的”; “红色的”; “白色的”; “白”]

应该变成:

[“红色”; “红色的”; “蓝色”; “绿色”; “绿色”; “忽略”; “忽视” ; “忽视”; “忽视”; “忽视”; "忽略"; "黄色"; “白色的”; “白色的”; “红色的”; “白色的”; “白”]

有什么想法吗?

【问题讨论】:

  • 你有什么想法吗?
  • 高效方式是主观的,你是指速度、内存、代码行数、可读性吗?无论哪种方式 O(n) for 循环,具有第一个索引、最后一个值和重复计数器。当达到阈值时,它将给定的单词覆盖到当前索引并继续前进。没有必要想太多。你可以喜欢 Linq 但我认为这会不太直观
  • MoreLinq 的 GroupAdjacent 是您可以开始的地方。
  • 如何枚举列表,跟踪前一个值,以及第一个相同值的索引?

标签: c# arrays list duplicates contiguous


【解决方案1】:

正如 cmets 中所说,使用 GroupAdjacent 使用 nuget 包 MoreLinq 对连续重复进行分组是一种选择:

var strings = new List<string> { "red", "red", "blue", "green", "green", "red", "red", "red", "red", "red", "red", "yellow", "white", "white", "red", "white", "white" };

var result = strings
    .GroupAdjacent(x => x)
    .SelectMany(grp => (grp.Count() >= 5) ?
                grp.Select(x => "ignore") : 
                grp);

Console.WriteLine("{ " + string.Join(", ", result) + " }");

结果:

{ red, red, blue, green, green, ignore, ignore, ignore, ignore, ignore, ignore, yellow, white, white, red, white, white }

上面还使用Enumerable.SelectMany将分组的IEnumerable&lt;IEnumerable&lt;string&gt;&gt;序列展平为IEnumerable&lt;string&gt;,然后使用三元运算符来决定该组是否应该完全替换为"ignore"和Enumerable.Select,如果组长来自Enumerable.Countis 大于或等于 5,或保持原样。

【讨论】:

    猜你喜欢
    • 2015-12-03
    • 2020-06-12
    • 2021-10-31
    • 1970-01-01
    • 2022-12-17
    • 1970-01-01
    • 2021-11-21
    • 1970-01-01
    相关资源
    最近更新 更多