0

I am trying to extract distinct objects by their values to have the unique CurrencyISO I have in the .csv.

public List<CurrencyDetail> InitGSCheckComboCurrency()
{
    var lines = File.ReadAllLines("Data/AccountsGSCheck.csv");
    var data = (from l in lines.Skip(1)
                let split = l.Split(',')
                select new CurrencyDetail
                {
                    ISOName = split[3],
                    ISOCode = split[3]
                }).Distinct();

    List<CurrencyDetail> lstSrv = new List<CurrencyDetail>();
    lstSrv = data.ToList();

    return lstSrv;
}

However, the distinct function does not work for this and I end up with duplications.

Thomas Flinkow
  • 4,845
  • 5
  • 29
  • 65
Ran
  • 65
  • 1
  • 7
  • 2
    Typo? Both `ISOName` and `ISOCode` are *third* - `split[3]` - items? – Dmitry Bychenko Jun 04 '18 at 12:00
  • Important distinction, do you want the distinct values or the unique ones? For instance if you have 1,2,2,3 the distinct values are 1,2,3 but the unique ones are 1,3. – juharr Jun 04 '18 at 12:11

1 Answers1

1

You would need to define the Equals and GetHashCode of CurrencyDetail to do what you want. Quick and dirty solution:

var data = (from l in lines.Skip(1)
           let split = l.Split(',')
           select new
           {
               ISOName = split[3],
               ISOCode = split[3]
           }).Distinct()
           .Select(x => new CurrencyDetail
           {
               ISOName = x.ISOName,
               ISOCode = x.ISOCode
           };

Anonymous types (the first new { ... }) automatically define sensible Equals() and GetHashCode(). Normally I wouldn't do this, because you are creating objects to then discard them. For this reason it is a quick and dirty solution.

Note that you are using twice split[3]... an error?

Now, a fully equatable version of CurrencyDetail could be:

public class CurrencyDetail : IEquatable<CurrencyDetail>
{
    public string ISOName { get; set; }
    public string ISOCode { get; set; }

    public override bool Equals(object obj)
    {
        // obj is object, so we can use its == operator
        if (obj == null)
        {
            return false;
        }

        CurrencyDetail other = obj as CurrencyDetail;

        if (object.ReferenceEquals(other, null))
        {
            return false;
        }

        return this.InnerEquals(other);
    }

    public bool Equals(CurrencyDetail other)
    {
        if (object.ReferenceEquals(other, null))
        {
            return false;
        }

        return this.InnerEquals(other);
    }

    private bool InnerEquals(CurrencyDetail other)
    {
        // Here we know that other != null;

        if (object.ReferenceEquals(this, other))
        {
            return true;
        }

        return this.ISOName == other.ISOName && this.ISOCode == other.ISOCode;
    }

    public override int GetHashCode()
    {
        unchecked
        {
            // From http://stackoverflow.com/a/263416/613130
            int hash = 17;
            hash = hash * 23 + (this.ISOName != null ? this.ISOName.GetHashCode() : 0);
            hash = hash * 23 + (this.ISOCode != null ? this.ISOCode.GetHashCode() : 0);
            return hash;
        }
    }
}

With this you can use the Distinct() as used by your code.

xanatos
  • 109,618
  • 12
  • 197
  • 280