1

我有一个List<CreditCard>, 信用卡的一个属性是CreditCardNumber, 它是一个字符串。不幸的是,它可以是1234 1234 1234 12341234123412341234,它们都是相同的数字。

我需要检查并删除这些重复的项目。有人可以帮忙吗?

4

7 回答 7

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();
}
于 2012-11-12T22:57:14.073 回答
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();
    }
}
于 2012-11-12T23:04:10.650 回答
0
  1. 删除每个空格
  2. 采用Distinct();
于 2012-11-12T22:57:40.957 回答
0

您可以创建自己EqualityComparerCreditCard删除空格并用于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());
于 2012-11-12T22:57:41.630 回答
0

首先,您必须确定什么构成“相等”。如果它像删除嵌入空格一样简单,那么您可以使用以前的解决方案之一来删除空格并调用Distinct. 否则,您必须创建一个相等比较器并将其传递给Distinct 重载

于 2012-11-12T22:59:53.523 回答
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()   ???
于 2012-11-12T23:05:27.793 回答
0

您只能从任何字符串中提取数字,在您的情况下,您只能将空格字符替换为空字符,对于更复杂的字符串格式,您可以使用下一个代码仅获取数字。您可以检查此答案:仅获取数字

string justNumbers = new String("asd123 f3 4.34-3 ".Where(Char.IsDigit).ToArray());

然后你将只有你的数字,CreditCardNumber你可以搜索重复的值。

于 2012-11-13T00:27:21.163 回答