我有一个List<CreditCard>
,信用卡的属性是CreditCardNumber
,这是一个字符串。不幸的是,它们可以是1234 1234 1234 1234
或1234123412341234
,它们都是相同的数字。
我需要检查并删除这些重复的项目。有人可以帮忙吗?
答案 0 :(得分:5)
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();
}
答案 1 :(得分:2)
最佳选择是在输入时从卡号中删除空格,这样您只需执行一次清洁操作:
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();
}
}
答案 2 :(得分:0)
Distinct();
答案 3 :(得分:0)
您可以为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());
答案 4 :(得分:0)
首先,您必须确定什么构成“平等”。如果它像删除嵌入空格一样简单,那么您可以使用以前的解决方案之一来删除空格并调用Distinct
。否则,您必须创建一个相等比较器并将其传递给Distinct overload。
答案 5 :(得分:0)
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() ???
答案 6 :(得分:0)
您只能从任何字符串中提取数字,在这种情况下,您只能替换空字符的空格字符,对于更复杂的字符串格式,您可以使用下一个代码仅获取数字。您可以查看以下答案:get only digits
string justNumbers = new String("asd123 f3 4.34-3 ".Where(Char.IsDigit).ToArray());
然后您将只拥有CreditCardNumber
的数字,并且可以搜索重复的值。