【问题标题】:How to find groups of n or more sequentially repeated items in a list c#如何在列表c#中查找包含n个或更多顺序重复项的组
【发布时间】:2021-05-30 17:34:20
【问题描述】:

如何找到 n 和更多 'b' 字符的组并将它们放入新列表中?
组 - 我想找到的 n 'b' 的数量。

示例:

List<char> charlist = new List<char>() {
  'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'b', 'b'
};

我想将 所有 'b' 放入连续重复 3 次或更多次 的新数组中

结果:

列表中的 'b' 总数 = 8
添加到数组 = 734 项组合);

List<char> newCharList = new List<char>() {'b', 'b', 'b', 'b', 'b', 'b', 'b'};

【问题讨论】:

  • 那么你只想要char[] charArray = charlist.Where(c == 'b').ToArray();
  • @John - 不,看来他只想要 3 个 bs 的组。输入有 7 个bs,但输出有 6 个。
  • OP:什么构成了一个团队?它总是 3 人一组,还是 2+ b 字符的所有实例都被视为组?
  • 是的,现在清楚了。也许他们会重新打开它,以便有人可以发布答案。不过,引用的链接应该对您有所帮助。只需创建一个 List&lt;char&gt; 以添加相邻的 bs ONLY。
  • 如果它实际上只是字符并且没​​有更复杂的东西,我可能会将字符数组转换为字符串并使用正则表达式:var ms = Regex.Matches(new string(array), "b{3,}") 然后将匹配项粘在一起或按顺序处理它们的字符,例如foreach(char c in string.Join("", ms.Select(m =&gt; m.Grous[0].Value))

标签: c# arrays list linq


【解决方案1】:

嗯,一个简单的foreach 循环应该在generalized 的情况下执行;让我们将例程实现为枚举:

  using System.Linq;

  ... 

  private static IEnumerable<T> MyExtraction<T>(IEnumerable<T> source, 
                                                Func<T, bool> selectItem, 
                                                Func<List<T>, bool> selectGroup) {
    List<T> cache = new List<T>();

    foreach (T item in source) {
      if (selectItem(item))
        cache.Add(item);
      else if (cache.Count > 0) { // if we have anything to output 
        if (selectGroup(cache))   // should we output?
          foreach (T result in cache)
            yield return result;   

        cache.Clear();
      }
    } 

    if (cache.Count > 0 && selectGroup(cache))
      foreach (T result in cache)
        yield return result;  
  }

那么我们可以这样使用它:

  List<char> charlist = new List<char>() { 
    'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'b', 'b' 
  };

  List<char> newCharList = MyExtraction(
     charlist,                   // process charlist
     item => item == 'b',        // extract 'b' 
     group => group.Count >= 3)  // take all groups which size >= 3
  .ToList();                     // materialize as List

  // Let's have a look
  Console.Write(string.Join(", ", newCharList));

结果:7 项 - 34 项组合)

  b, b, b, b, b, b, b  

【讨论】:

    【解决方案2】:

    这是一个方便的扩展方法:

    public static IEnumerable<IEnumerable<T>> GroupByEquals<T>(this IEnumerable<T> source)
    {
        var enumerator = source.GetEnumerator();
        var current = default(T);
        var loop = false;
        
        IEnumerable<T> ProduceSame()
        {
            yield return enumerator.Current;
            while (enumerator.MoveNext())
            {
                if (!enumerator.Current.Equals(current))
                {
                    loop = true;
                    yield break;
                }
                yield return enumerator.Current;
            }
            loop = false;
        }
    
        while (loop || enumerator.MoveNext())
        {
            current = enumerator.Current;
            yield return ProduceSame().ToArray();
        }
    }
    

    这需要以下字符列表:

    List<char> charlist = new List<char>()
    {
        'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'b', 'b'
    };
    

    并产生:

    然后将其转换为所需的结果是微不足道的:

    List<char> newCharList =
        charlist
            .GroupByEquals()
            .Where(xs => xs.Count() >= 3 && xs.All(x => x == 'b'))
            .SelectMany(x => x)
            .ToList();
    

    【讨论】:

      【解决方案3】:

      这样怎么样:

      List<char> charlist = new List<char>() { 'b', 'a', 'b', 'b', 'b', 'a', 'b', 'b', 'b', 'b' };
      
      int repeatCounts = 0;
      List<char> result = new List<char>();
      foreach (var c in charlist)
      {
          if (c == 'b')
          {
              repeatCounts++;
              continue;
          }
      
          if (repeatCounts >= 3)
          {
              result.AddRange(Enumerable.Repeat('b', repeatCounts));
          }
      
          repeatCounts = 0;
      }
      
      if (repeatCounts >= 3)
      {
          result.AddRange(Enumerable.Repeat('b', repeatCounts));
      }
      
      foreach (var r in result)
      {
          Console.Write(r);
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-02-16
        • 2012-06-15
        • 2012-09-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多