Find continuous duplicates in a List

牧云@^-^@ 提交于 2021-01-28 04:13:21

问题


There are loads of ways to find to find Duplicates in a list, is There any way to find continuous duplicates in a List.

For example

List<string> stringList = new List<string>();
stringList.Add("Name1");
stringList.Add("Name2");
stringList.Add("Name1");

Shouldn't find any but

stringList.Add("Name1");
stringList.Add("Name1");
stringList.Add("Name2"); 

Should return 1 Entry

This returns duplicates.

 var q = listString.GroupBy(x => x)
         .Select(g => new { Value = g.Key, Count = g.Count() })
         .OrderByDescending(x => x.Count);

回答1:


Why not just store the last item? Something like this

public static partial class EnumerableExtensions { 
  // Simplest; IEquatable<T> for advanced version
  public static IEnumerable<T> Continuous<T>(this IEnumerable<T> source) {
    if (null == source)
      throw new ArgumentNullException("source");  

    T lastItem = default(T);
    Boolean first = true;

    foreach (var item in source) {
      if (first) {
        lastItem = item;
        first = false;
      }
      else if (Object.Equals(item, lastItem)) 
        yield return item;
      else
        lastItem = item; 
    }
  }  
}

And then

List<string> stringList = new List<string>() {
  "Name1",
  "Name1",
  "Name2",
};

var contDups = stringList
  .Continuous() 
  .ToList();



回答2:


Here is one way to do it that returns the duplicate items and their indexes:

var duplicates =
    stringList
    .Select((x,i) => new {Item = x, Index = i})
    .Skip(1) //We start with the second item
    .Where(y => y.Item == stringList[y.Index-1])
    .ToList();



回答3:


Since you asked "If we can get which item is duplicate and starting index and number of occurrences", here's a solution to that particular requirement.

This outputs the following:

2 was repeated 2 times starting at index 1
3 was repeated 3 times starting at index 4
4 was repeated 4 times starting at index 8

Here's the code:

using System;
using System.Collections.Generic;

namespace Demo
{
    class DupeInfo
    {
        public string Text;
        public int Index;
        public int Count;
    }

    static class Program
    {
        static void Main()
        {
            var test = new[]
            {
                "1",
                "2", "2",
                "A",
                "3", "3", "3",
                "B",
                "4", "4", "4", "4",
                "C",
            };

            foreach (var dupeinfo in FindRepeats(test))
                Console.WriteLine($"{dupeinfo.Text} was repeated {dupeinfo.Count} times starting at index {dupeinfo.Index}");
        }

        public static IEnumerable<DupeInfo> FindRepeats(IEnumerable<string> input)
        {
            int i = 0;
            int j = 0;
            int c = -1;

            string prev = null;

            foreach (var curr in input)
            {
                if (curr != prev)
                {
                    if (c >= 0)
                        yield return new DupeInfo {Text = prev, Count = c + 2, Index = j};

                    c = -1;
                    j = i;
                }
                else
                {
                    ++c;
                }

                prev = curr;
                ++i;
            }

            if (c >= 0)
                yield return new DupeInfo {Text = prev, Count = c + 2, Index = j};
        }
    }
}



回答4:


You can start from defining what it means for an item to be a "consecutive duplicate":

An item at position i is a consecutive duplicate if it is the same as the item at position i-1

One way to compare a value with another value in a prior position is to use Zip with a list "shifted over" by one element:

var consecutiveDuplicates = list.Skip(1)
    .Zip(list, (me, prior) => new {ThisItem = me, Prior = prior})
    .Where(p => p.ThisItem == p.Prior)
    .Select(p => p.ThisItem) // Both sides are equal, pick either one
    .ToList();

list.Skip(1).Zip(list,...) expression combines the list with itself with a shift of 1, so you can get this element and its prior element for N-1 positions where prior element is defined. The rest is a straightforward translation of English definition into LINQ statements



来源:https://stackoverflow.com/questions/36935592/find-continuous-duplicates-in-a-list

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!