我有一个代表美国邮政编码的整数列表,我希望根据邮政编码的前三位数得到唯一值。例如,这是我的清单:
10433
30549
10456
54933
60594
30569
30659
我的结果应仅包含:
10433
30549
54933
60594
30659
从我的列表中排除的美国邮政编码是: 10456 和 30659 ,因为我已经拥有包含104xx和306xx的ZIP。
我真的不知道怎么做到这一点,我想这并不难,但我不知道。我已经创建了一个函数,它为我保存了前三位数字,并且我在每个zip的末尾添加了一些随机的2位数字。但它没有成功,因为我得到了例如10423但10423不在我的列表中,并且我没有特定的模式,我的所有数字都有一个范围内的最后2位数。
答案 0 :(得分:12)
一点Linq应该工作。如果使用int
s列表:
var zips = new[] { 10433, 30549, 10456, 54933, 60594, 30569, 30659 };
var results = zips.GroupBy(z => z / 100).Select(g => g.First());
或者如果使用string
s列表:
var zips = new[] { "10433", "30549", "10456", "54933", "60594", "30569", "30659" };
var results = zips.GroupBy(z => z.Remove(3)).Select(g => g.First());
另一种解决方案是使用自定义IEqualityComparer<T>
。对于int
s:
class ZipComparer : IEqualityComparer<int> {
public bool Equals(int x, int y) {
return x / 100 == y / 100;
}
public int GetHashCode(int x) {
return x / 100;
}
}
对于string
s:
class ZipComparer : IEqualityComparer<string> {
public bool Equals(string x, string y) {
return x.Remove(3) == y.Remove(3);
}
public int GetHashCode(string x) {
return x.Remove(3).GetHashCode();
}
}
然后使用它,您只需拨打Distinct
:
var result = zips.Distinct(new ZipComparer());
最后,您还使用了MoreLINQ的DistinctBy
扩展方法(也可在NuGet上找到):
var results = zips.DistinctBy(z => z / 100);
// or
var results = zips.DistinctBy(z => z.Remove(3));
答案 1 :(得分:2)
这里流行的答案给出了代码,但没有解决问题。问题是你似乎没有算法。所以......
您如何在纸上解决此问题?
我认为这个过程会是这样的:
你会如何在代码中写这个?
嗯,你需要一些东西:
这是编写此内容的一种方法(您可以将其转换为使用字符串作为练习):
ICollection<int> GetUniqueZipcodes(int[] zips)
{
Dictionary<int, int> bucket = new Dictionary<int,int>();
foreach (var zip in zips)
{
int prefix = GetPrefix(zip);
if(!bucket.ContainsKey(prefix))
{
bucket.Add(prefix, zip);
}
}
return bucket.Values;
}
int GetPrefix(int zip)
{
return zip / 100;
}
简明扼要
现在,如今许多程序员都会说“OMG这么多行代码可能只是一行代码”。他们是对的,它可以。借用p.s.w.g的答案,这可以(以一种非常易读的方式)浓缩为:
var results = zips.GroupBy(z => z / 100).Select(g => g.First());
那么这是如何工作的? zips.GroupBy(z => z/100)
执行分段操作。最终会得到一组如下所示的组:
{
104: { 10433, 10456 },
305: { 30549, 30569 },
549: { 54933 },
605: { 60594 },
306: { 30659 }
}
然后我们使用.Select(g => g.First())
,它从每个组中获取第一项。