如何从可用产品版本列表中返回最佳匹配/下一个可用产品版本ID?
以下是基于表
中的样本数据的逻辑查找小于10.10.20的最佳匹配版本,并返回其versionID eg1:GetVersion(“10.10.20”)应该返回5(因为在表中没有“10,10,20”major.minor.build组合可用,所以它应该寻找最匹配的版本 这里的下一个可用版本是10.7.1 ie。,versionID 5
eg2:GetVersion(“7.0.0”)应该返回3(因为在表中没有“7,0,0”major.minor.build组合可用,所以它应该寻找下一个可用的匹配版本。 下一个可用版本是6.2.1即。,版本ID 3
eg3:GetVersion(“7.5.1”)应返回4,此处完全匹配可用,因此应返回versionid 4
[Serializable]
public class ProductVersions
{
[Key]
public int Version_Id { get; set; }
public int Major { get; set; }
public int Minor { get; set; }
public int Build { get; set; }
}
以下是我的ProductVersions表中的一些示例数据
[version_id , Major,Minor,Build]
1 3 0 1
2 4 10 5
3 6 2 1
4 7 5 1
5 10 7 1
6 11 10 10
这是我的方法,预计将返回最佳可用产品版本
private int GetVersion(string versionNumber)
{
int version-id=0;
version-id= //retrieve best matching version
return version-id
}
答案 0 :(得分:1)
您可以使用内置版本类,因为它已经实现了您基本上正在寻找的<=
运算符,并且还可以为您处理字符串解析:
var data = new List<Version>()
{
new Version(3,0,1),
new Version(4,10,5),
new Version(6,2,1),
new Version(7,5,1),
new Version(10,7,1),
new Version(11,10,10)
};
var case1 = new Version("10.10.20");
// match1 is 5; the index of a List is 0-based, so we add 1
var match1 = data.FindLastIndex(d => d <= case1) + 1;
var case2 = new Version("7.0.0");
// match2 is 3
var match2 = data.FindLastIndex(d => d <= case2) + 1;
var case3 = new Version("7.5.1");
// match3 is 4
var match3 = data.FindLastIndex(d => d <= case3) + 1;
将ProductVersions
的序列转换为Version
个对象列表应该是微不足道的。
如果您出于某种原因不想使用Version
类,您可以自己实现<=
(以及所有其他缺少的运算符):
public class ProductVersions
{
//TODO error checking
public int Version_Id { get; set; }
public int Major { get; set; }
public int Minor { get; set; }
public int Build { get; set; }
public ProductVersions(int major, int minor, int build)
{
Major=major;
Minor=minor;
Build=build;
}
public ProductVersions(string version)
{
var tmp = version.Split('.');
Major = Int32.Parse(tmp[0]);
Minor = Int32.Parse(tmp[1]);
Build = Int32.Parse(tmp[2]);
}
public static bool operator == (ProductVersions a, ProductVersions b)
{
return a.Major==b.Major && a.Minor==b.Minor && a.Build==b.Build;
}
public static bool operator != (ProductVersions a, ProductVersions b)
{
return !(a==b);
}
public static bool operator <= (ProductVersions a, ProductVersions b)
{
if (a == b)
return true;
return a < b;
}
public static bool operator >= (ProductVersions a, ProductVersions b)
{
if (a == b)
return true;
return a > b;
}
public static bool operator < (ProductVersions a, ProductVersions b)
{
if(a.Major==b.Major)
if(a.Minor==b.Minor)
return a.Build < b.Build;
else
return a.Minor < b.Minor;
else
return a.Major < b.Major;
}
public static bool operator > (ProductVersions a, ProductVersions b)
{
if(a.Major==b.Major)
if(a.Minor==b.Minor)
return a.Build > b.Build;
else
return a.Minor > b.Minor;
else
return a.Major > b.Major;
}
一个简单的测试:
var data = new List<ProductVersions>()
{
new ProductVersions(3,0,1) { Version_Id = 1},
new ProductVersions(4,10,5) { Version_Id = 2},
new ProductVersions(6,2,1) { Version_Id = 3},
new ProductVersions(7,5,1) { Version_Id = 4},
new ProductVersions(10,7,1) { Version_Id = 5},
new ProductVersions(11,10,10) { Version_Id = 6}
};
// ensure data is sorted by version
data.Sort((a,b) => a > b ? 1 : a < b ? -1 : 0);
var case1 = new ProductVersions("10.10.20");
// match1 is 5
var match1 = data.Last(d => d <= case1).Version_Id;
var case2 = new ProductVersions("7.0.0");
// match2 is 3
var match2 = data.Last(d => d <= case2).Version_Id;
var case3 = new ProductVersions("7.5.1");
// match3 is 4
var match3 = data.Last(d => d <= case3).Version_Id;
答案 1 :(得分:1)
我喜欢Dominic使用版本类的答案(为什么发明它存在?)但是如果您想知道如何在不使用Version类的情况下执行此操作并且您认为列表已经排序(因此您不需要需要像他那样对它进行排序。
(TL; DR)
// assume verArray is already ordered (this would need to be sorted otherwise.)
// this where checks for less than or equal to.
int result = verArray.Where(v => (v.Major < major) ||
(v.Major == major && v.Minor < minor) ||
(v.Major == major && v.Minor == minor && v.Build <= build))
.Last().Version_Id;
完整的代码和测试:
public ProductVersions[]verArray = {
new ProductVersions() { Version_Id = 1, Major = 3, Minor = 0, Build = 1 },
new ProductVersions() { Version_Id = 2, Major = 4, Minor = 10, Build = 5 },
new ProductVersions() { Version_Id = 3, Major = 6, Minor = 2, Build = 1 },
new ProductVersions() { Version_Id = 4, Major = 7, Minor = 5, Build = 1 },
new ProductVersions() { Version_Id = 5, Major = 10, Minor = 7, Build = 1 },
new ProductVersions() { Version_Id = 6, Major = 11, Minor = 10, Build = 10 },
};
void Main()
{
string test = "10.10.20";
Console.WriteLine(test + " gives "+GetVersion(test));
test = "7.0.0";
Console.WriteLine(test + " gives "+GetVersion(test));
test = "7.5.1";
Console.WriteLine(test + " gives "+GetVersion(test));
}
private int GetVersion(string versionNumber)
{
string [] input = versionNumber.Split(".".ToCharArray());
int major = int.Parse(input[0]);
int minor = int.Parse(input[1]);
int build = int.Parse(input[2]);
// assume verArray is already ordered (this would need to be sorted otherwise.
int result = verArray.Where(v => (v.Major < major) ||
(v.Major == major && v.Minor < minor) ||
(v.Major == major && v.Minor == minor && v.Build <= build))
.Last().Version_Id;
return result;
}
public class ProductVersions
{
public int Version_Id { get; set; }
public int Major { get; set; }
public int Minor { get; set; }
public int Build { get; set; }
}
返回以下内容:
10.10.20 gives 5
7.0.0 gives 3
7.5.1 gives 4
答案 2 :(得分:-3)
我刚检查了你给的样品。这段代码适合我。
private int getver(int m, int n, int b)
{
List<ProductVersions> pv = new List<ProductVersions>();
pv.Add(new ProductVersions { Version_Id = 3, Major = 6, Minor = 2, Build = 1 });
pv.Add(new ProductVersions { Version_Id = 4, Major = 7, Minor = 5, Build = 1 });
pv.Add(new ProductVersions { Version_Id = 5, Major = 10, Minor = 7, Build = 1 });
pv.Add(new ProductVersions { Version_Id = 6, Major = 11, Minor = 10, Build = 10 });
int mm = m;
if (m == 0)
mm = int.MaxValue;
int nn = n;
if (n == 0)
nn = int.MaxValue;
int bb = b;
if (b == 0)
bb = int.MaxValue;
var v = pv.FindAll(mj => mj.Major <= m).FindAll(mn => n == 0 ? mn.Major <= mm - 1 && mn.Minor <= nn : mn.Minor <= n).FindAll(bl => b == 0 ? bl.Minor <= nn - 1 && bl.Build <= bb : bl.Build <= b).Last().Version_Id;
return v;
}
我正在尝试根据主要,次要和构建级别的标准缩小列表并获取列表的最后一个实体。这里我假设列表是根据这些值排序的。
答案 3 :(得分:-3)
我发现这是一种快速而简单的方法,但有一些限制。
var v = from p in pv
select new { version = p.Version_Id, val = p.Major * 100000000 + p.Minor * 10000 + p.Build };
int vver=v.ToList().FindAll(pp => pp.val <= m * 100000000 + n * 10000 + b).Last().version;