我需要从List<>中删除重复项

时间:2012-11-12 22:52:30

标签: c# list

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

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

7 个答案:

答案 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)

  1. 从每个
  2. 中删除空白区域
  3. 使用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的数字,并且可以搜索重复的值。