извлечение общих префиксов из списка строк - PullRequest
1 голос
/ 27 августа 2011

У меня есть список строк, например:

{ abc001, abc002, abc003, cdef001, cdef002, cdef004, ghi002, ghi001 }

Я хочу получить все распространенные уникальные префиксы; например, для приведенного выше списка:

{ abc, cdef, ghi }

Как мне это сделать?

Ответы [ 4 ]

2 голосов
/ 27 августа 2011
var list = new List<String> {
    "abc001", "abc002", "abc003", "cdef001",
    "cdef002", "cdef004", "ghi002", "ghi001"
};
var prefixes = list.Select(x = >Regex.Match(x, @"^[^\d]+").Value).Distinct();
0 голосов
/ 27 августа 2011

Предполагая, что ваш префикс состоит из букв алфавита и оканчивается первым не алфавитом, вы можете использовать следующее выражение LINQ

List<string> listOfStrings = new List<String>() 
  { "abc001d", "abc002", "abc003", "cdef001", "cdef002", "cdef004", "ghi002", "ghi001" }; 

var prefixes = (from s in listOfStrings
                select new string(s.TakeWhile(c => char.IsLetter(c)).ToArray())).Distinct();
0 голосов
/ 27 августа 2011

Может быть хорошей идеей написать вспомогательный класс для представления ваших данных. Например:

public class PrefixedNumber
{
    private static Regex parser = new Regex(@"^(\p{L}+)(\d+)$");

    public PrefixedNumber(string source) // you may want a static Parse method.
    {
        Match parsed = parser.Match(source); // think about an error here when it doesn't match
        Prefix = parsed.Groups[1].Value;
        Index = parsed.Groups[2].Value;
    }

    public string Prefix { get; set; }
    public string Index { get; set; }
}

Вам, конечно, нужно придумать лучшее имя и лучшие модификаторы доступа.

Теперь задача довольно проста:

List<string> data = new List<string> { "abc001", "abc002", "abc003", "cdef001",
                                       "cdef002", "cdef004", "ghi002", "ghi001" };
var groups = data.Select(str => new PrefixedNumber(str))
                 .GroupBy(prefixed => prefixed.Prefix);

Результатом являются все данные, проанализированные и сгруппированные по префиксу.

0 голосов
/ 27 августа 2011

Вы можете добиться этого, используя Регулярное выражение для выделения текстовой части, а затем используйте HashSet<string>, чтобы добавить эту текстовую часть, чтобы не было дублирования:

using System.Text.RegularExpressions;


//simulate your real list 
List<string> myList = new List<string>(new string[] { "abc001", "abc002", "cdef001" });   

string pattern = @"^(\D*)\d+$";
//  \D* any non digit characters, and \d+ means followed by at least one digit,
// Note if you want also to capture string like "abc" alone without followed by numbers
// then the pattern will be "^(\D*)$"

Regex regex = new Regex(pattern);

HashSet<string> matchesStrings = new HashSet<string>();

foreach (string item in myList)
{
    var match = regex.Match(item);

    if (match.Groups.Count > 1)
    {
        matchesString.Add(match.Groups[1].Value);
    }
}

результат:

abc, cde
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...