我有一个List<CreditCard>
, 信用卡的一个属性是CreditCardNumber
, 它是一个字符串。不幸的是,它可以是1234 1234 1234 1234
或1234123412341234
,它们都是相同的数字。
我需要检查并删除这些重复的项目。有人可以帮忙吗?
using System.Linq;
public List<string> GetUniqueCardNumbers(List<string> cardNumbers)
{
// First replace the spaces with empty strings
return cardNumbers.Select(cc => cc.Replace(" ", ""))
.Distinct()
.ToList();
}
最好的选择是在输入时从卡号中删除空格,这样您只需执行一次清洁操作:
public class CreditCard: IComparable<CreditCard>
{
string creditCardNumberClean;
string creditCardNumberOriginal;
public string CreditCardNumber
{
get
{
return this.creditCardNumberOriginal;
}
set
{
this.creditCardNumberOriginal = value;
this.creditCardNumberClean = value.Replace(" ", "");
}
}
public CreditCard(string creditCardNumber)
{
this.CreditCardNumber = creditCardNumber;
}
public int CompareTo(CreditCard other)
{
return this.creditCardNumberClean.CompareTo(other.creditCardNumberClean);
}
}
但是,如果这不可能,您基本上想对卡号执行字符串比较,只需在比较之前改变数字以删除所有空格:
class Program
{
public static void Main(string[] args)
{
List<string> list = new List<string>(new string[]{"1234 1234 1234 1234", "1234123412341234","9999 9999 9999 9999"});
SortedSet<string> set = new SortedSet<string>(list, new CreditCardNoComparer());
foreach (string s in set)
{
Console.WriteLine(s);
}
Console.ReadKey();
}
}
public class CreditCardNoComparer : IComparer<string>
{
public int Compare(string x, string y)
{
return x.Replace(" ", "").CompareTo(y.Replace(" ", ""));
}
}
编辑
//version using overridden GetHashCode and Equals methods as per @lazyberezovsky's comments
public class CreditCard
{
long creditCardNumberClean; //given the card number is numeric this is the most efficient way of storing it
string creditCardNumberOriginal;
public string CreditCardNumber
{
get
{
return this.creditCardNumberOriginal;
}
set
{
this.creditCardNumberOriginal = value;
this.creditCardNumberClean = long.Parse(value.Replace(" ", ""));
}
}
public CreditCard(string creditCardNumber)
{
this.CreditCardNumber = creditCardNumber;
}
public override bool Equals(object obj)
{
CreditCard other = obj as CreditCard;
return
other == null
? false
: this.creditCardNumberClean.Equals(other.creditCardNumberClean);
}
public override int GetHashCode()
{
return this.creditCardNumberClean.GetHashCode();
}
}
Distinct();
您可以创建自己EqualityComparer
的CreditCard
删除空格并用于Enumerable.Distinct
删除重复项:
public class CardComparer : IEqualityComparer<CreditCard>
{
private readonly Regex re = new Regex(@"\s+");
public bool Equals(CreditCard x, CreditCard y)
{
return re.Replace(x.Number, "") == re.Replace(y.Number, "");
}
public int GetHashCode(CreditCard obj)
{
return re.Replace(obj.Number, "").GetHashCode();
}
}
然后:
IEnumerable<CreditCard> unique = sourceList.Distinct(new CardComparer());
首先,您必须确定什么构成“相等”。如果它像删除嵌入空格一样简单,那么您可以使用以前的解决方案之一来删除空格并调用Distinct
. 否则,您必须创建一个相等比较器并将其传递给Distinct 重载。
IEnumerable<CreditCard> distinctCards = cards
.Select(card => new {
card,
ccn = card.CreditCardNumber.Replace(" ", string.Empty)
})
.GroupBy(x => x.ccn)
.Select(g => g.First().card) //group has at least 1 member, so First() is safe
//.ToList() ???
您只能从任何字符串中提取数字,在您的情况下,您只能将空格字符替换为空字符,对于更复杂的字符串格式,您可以使用下一个代码仅获取数字。您可以检查此答案:仅获取数字
string justNumbers = new String("asd123 f3 4.34-3 ".Where(Char.IsDigit).ToArray());
然后你将只有你的数字,CreditCardNumber
你可以搜索重复的值。