选择包含更高编号的字符串

时间:2012-09-06 10:39:57

标签: c# string list

我有一个字符串列表。

列出项目如下:

CM_Manual_EN_rev.01   
CM_Manual_EN_rev.02   
CM_Manual_EN_REV.05   
CM_Manual_EN_REV.06   
CM_Manual_EN_REV.07   
...   
CM12-CM6K_Spare_parts_DK_rev.01    
CM12-CM6K_Spare_parts_DK_rev.03   
...
BT_Dansk_Manual_NOM
CM_Svensk_Manual
CM901-CM30_Manual_RUS
D_Polsk_Manual
HPB_spansk_old

如果他们有rev.number我想添加到列表框只是highest rev.number 的列表框,

如果他们没有rev.number ,这意味着它是唯一的版本,然后将其简单地添加到列表框中。

感谢您的帮助!

4 个答案:

答案 0 :(得分:2)

这对我有用:

Func<string, Tuple<string, int>> split = t =>
{
    var a = t
        .ToLowerInvariant()
        .Split(new [] { "rev." }, StringSplitOptions.None);
    return Tuple.Create(a[0], a.Length == 2 ? int.Parse(a[1]) : 0);
};

var query =
    from i in items
    let s = split(i)
    group new { i, s.Item2 } by s.Item1 into g
    from m in g
        .OrderByDescending(x => x.Item2)
        .Take(1)
        .Select(x => x.i)
    select m;

我从这个输入开始:

var items = new []
{
    "CM_Manual_EN_rev.01",
    "CM_Manual_EN_rev.02",
    "CM_Manual_EN_REV.05",
    "CM_Manual_EN_REV.06",
    "CM_Manual_EN_REV.07",
    "Foo", 
    "CM12-CM6K_Spare_parts_DK_rev.01",
    "CM12-CM6K_Spare_parts_DK_rev.03",
};

得到了这个输出:

CM_Manual_EN_REV.07
Foo
CM12-CM6K_Spare_parts_DK_rev.03

答案 1 :(得分:1)

修改(将我的旧方法移至最底层)

既然您已经让我帮助您发表评论,这里有一种不同的方法可以满足您的需求:

您的样本数据(前四行是您的最新要求):

var list = new List<String>(){
    "CM901K_Spare_parts_EN_rev.04-2", 
    "CM901K_Spare_parts_EN_rev.04-1",
    "CM901K_Spare_parts_EN_rev.04-3",
    "CM901K_Spare_parts_EN_rev.04-2", 
    "rev.04-2",
    "CM_Manual_EN_rev.01", 
    "CM_Manual_EN_rev.02",  
    "CM_Manual_EN_REV.05",   
    "CM_Manual_EN_REV.06",   
    "CM_Manual_EN_REV.07",   
    "CM12-CM6K_Spare_parts_DK_rev.01",    
    "CM12-CM6K_Spare_parts_DK_rev.03",   
    "BT_Dansk_Manual_NOM",
    "CM_Svensk_Manual",
    "CM901-CM30_Manual_RUS",
    "D_Polsk_Manual",
    "HPB_spansk_old"
};

首先没有修订,然后按修订排序另一个(每组最高):

var withRev = list.Where(s => s.IndexOf("rev.", StringComparison.OrdinalIgnoreCase) > -1);
var withoutRev = list.Except(withRev);

var orderedWithRev = withRev
    .Select(r => { 
        int RevIndex = r.LastIndexOf("rev.", StringComparison.OrdinalIgnoreCase);
        String[] tokens = r
            .Substring(RevIndex + "rev.".Length)
            .Split(new[] { '-' }, StringSplitOptions.RemoveEmptyEntries);
        return new
        {
            Item = r,
            RevIndex,
            RevisionItem = r.Substring(0, RevIndex),
            MainRevision = int.Parse(tokens[0]),
            SubRevision  = tokens.Length > 1 ? int.Parse(tokens[1]) : 0
        };
    })
    .GroupBy(x => x.RevisionItem.ToLower())
    .Select(g => g
        .OrderByDescending(x => x.MainRevision)
        .ThenByDescending( x => x.SubRevision)
        .First().Item);

foreach (var wr in withoutRev)
    listBox1.Items.Add(wr);
foreach (var r in orderedWithRev)
    listBox1.Items.Add(r);

以下是演示:http://ideone.com/fGFZ7


老答案:

如果字符串始终高于格式,最简单的方法是使用Int32.ParseString.SubstringString.LastIndexofEnumerable.Max

int highestNum = list.Where(s => s.Contains("."))
                     .Max(s => int.Parse(s.Substring(s.LastIndexOf(".")+1)));

或获取字符串:

String highestNumString = list.Where(s => s.Contains("."))
                     .OrderByDescending(s => int.Parse(s.Substring(s.LastIndexOf(".")+1)))
                     .First();

修改:这是一个演示:http://ideone.com/0EeFg

答案 2 :(得分:0)

 var result = list
              .Where(s => s.Contains('.'))
              .OrderByDescending(s => int.Parse(s.Substring(s.LastIndexOf('.') + 1)))
              .GroupBy(s => s.Substring(0, s.LastIndexOf('.') + 1).ToLower())
              .Select(s => s.First())
              .Union(list.Where(s => !s.Contains('.')));

答案 3 :(得分:0)

您可以使用正则表达式从字符串中获取数字

string[] arr = { "CM_Manual_EN_rev.01", "CM_Manual_EN_rev.02", "CM_Manual_EN_rev.03" };
Regex re = new Regex(@"\d+");
foreach (string s in arr)
{
    Match m = re.Match(s);
    if (m.Success)
    {
        // use m.value to get highest no and compare then get index 
    }
}

我想现在你可以完成休息代码了