2012-09-06 41 views
0

我有一个字符串列表。选择包含较大数字的字符串

列表项目的样子:

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,这意味着它是唯一的版本,然后将其简单添加到列表框中。

谢谢你的帮忙!

回答

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

+0

有趣的方法,但是我觉得OP需要有对文本返回的每种类型软件中最高的,不是最高的数字。 – Enigmativity

+0

正好。我需要最高转速的字符串。数。在这种情况下是“CM_Manual_EN_REV.07”。谢谢 ! –

+0

@Enigmativity:在我再次阅读问题之后,已经编辑了我的答案。 –

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 
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('.'))); 
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 
    } 
} 

现在我认为你可以做其他的代码