none
Можно ли удалить дублирующие строки из MatchCollection при помощи .OfType<string>().GroupBy RRS feed

  • Вопрос

  • Добрый день,

     Задача: Есть MatchCollection, в нем содержатся строки дубликаты, т.е. 2 и более одинаковых строк. Из MatchCollection нужно удалить дубликаты.

    Вопрос: Можно ли удалить эти дубликаты при помощи MatchCollection.OfType<....>().GroupBy(.....)  или нечно похожего? Я пока не могу понять как пользоваться .GroupBy(.....)

    Код который решает задачу, но не эффективно:

    //Получаем MatchCollection, создаем еще один массив в который добавляем только уникальные значения.

    sString - большой текст

    sPattern - уловие по которому вырезаются строки из текста (но строки не уникальные).

     void fnCoolFunction(sString, sPattern)
                MatchCollection mGetString = Regex.Matches(sString, sPattern);

                //Add new array and put in it only new strings.
                string[] mGetStringWoDoubl = new string[mGetString.Count];

                for (int i = 0; i < mGetString.Count; i++)
                {
                    bool boolCheckDoublUri = true;
                    for (int i2 = 0; i2 < mGetStringWoDoubl.Length; i2++)
                    {
                        if (mGetStringWoDoubl[i2] == mGetString[i].Value)
                        {
                            boolCheckDoublUri = false;
                            break;
                        }
                    }
                    if (boolCheckDoublUri == true)
                    {
                        mGetStringWoDoubl[i] = mGetString[i].Value;
                    }
                }

    • Перемещено Siddharth Chavan 1 октября 2010 г. 21:31 MSDN Forums Consolidation (От:Visual C#)
    23 апреля 2010 г. 11:00

Ответы

  • Метод MatchCollection.OfType<string>() возвращает пустую коллекцию по тому с ним не поработать.

     public static void Main()
     {
      Regex rx = new Regex(@"\b[a-z]{3}\b");
      string text = "The the quick brown fox fox jumped over the lazy dog dog.";
      MatchCollection matches = rx.Matches(text);
      Console.WriteLine("{0} matches found in:\n {1}",
        matches.Count,
        text);
      List<string> allValues = new List<string>();
      HashSet<string> noDoubles = new HashSet<string>();
      foreach (Match match in matches)
      {
      Console.WriteLine(match.Value);
      allValues.Add(match.Value);
      noDoubles.Add(match.Value);
      }
      Console.WriteLine("----------------------");
      foreach (var group in allValues.GroupBy(x => x.GetHashCode()))
      {
      Console.WriteLine(group.First());
      }
      Console.WriteLine("----------------------");
      foreach (string str in noDoubles)
      {
      Console.WriteLine(str);
      }
     }

    В данном случае GroupBy относится к  List<string> по тому он будет принимать метод в качестве аргумента принимающий string и возвращающий int (возвращенное значение int должно быть одинаковым у всех членов одной группы) к примеру если вызвать  GetHashCode() у строки то равные строки вернут один и тот же результат и метод GroupBy соотнесет их в одну группу

    Так же можно использовать HashSet( T) - данная коллекция не может содержать двух одинаковы элементов

    • Помечено в качестве ответа EgoZa 23 апреля 2010 г. 14:37
    23 апреля 2010 г. 12:15

Все ответы

  • Метод MatchCollection.OfType<string>() возвращает пустую коллекцию по тому с ним не поработать.

     public static void Main()
     {
      Regex rx = new Regex(@"\b[a-z]{3}\b");
      string text = "The the quick brown fox fox jumped over the lazy dog dog.";
      MatchCollection matches = rx.Matches(text);
      Console.WriteLine("{0} matches found in:\n {1}",
        matches.Count,
        text);
      List<string> allValues = new List<string>();
      HashSet<string> noDoubles = new HashSet<string>();
      foreach (Match match in matches)
      {
      Console.WriteLine(match.Value);
      allValues.Add(match.Value);
      noDoubles.Add(match.Value);
      }
      Console.WriteLine("----------------------");
      foreach (var group in allValues.GroupBy(x => x.GetHashCode()))
      {
      Console.WriteLine(group.First());
      }
      Console.WriteLine("----------------------");
      foreach (string str in noDoubles)
      {
      Console.WriteLine(str);
      }
     }

    В данном случае GroupBy относится к  List<string> по тому он будет принимать метод в качестве аргумента принимающий string и возвращающий int (возвращенное значение int должно быть одинаковым у всех членов одной группы) к примеру если вызвать  GetHashCode() у строки то равные строки вернут один и тот же результат и метод GroupBy соотнесет их в одну группу

    Так же можно использовать HashSet( T) - данная коллекция не может содержать двух одинаковы элементов

    • Помечено в качестве ответа EgoZa 23 апреля 2010 г. 14:37
    23 апреля 2010 г. 12:15
  • Класс, Megano, как всегда, спасибо :)
    23 апреля 2010 г. 14:49
  • Небольшое дополнение - GetHashСode может вернуть одинаковый результат и для разных строк. Об этом явно написано в msdn по String.GetHashCode . Так что код выше будет признавать дубликатами совсем разные строки.

    Если цель - выбрать из MatchCollection уникальные строки, то все решается намного проще:

     

    var uniqueMatches = matches.OfType<Match>().Select(m => m.Value).Distinct().ToList();
    uniqueMatches.ForEach(Console.WriteLine);
    

     

    24 апреля 2010 г. 11:56