我有一个字符串列表。
列出项目如下:
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
,这意味着它是唯一的版本,然后将其简单地添加到列表框中。
感谢您的帮助!
答案 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.Parse
,String.Substring
,String.LastIndexof
和Enumerable.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
}
}
我想现在你可以完成休息代码了