SmackYouIn2.3
SmackYouIn2.3

Reputation: 31

Using distinct to remove duplicates

I have a class

class ShipmentsComparer : IEqualityComparer<Routes>
    {
        public bool Equals(Routes route1, Routes route2) =>
           route1.DockCode == route2.DockCode
           && route1.CarrierArrival == route2.CarrierArrival;

        public int GetHashCode(Routes obj) =>
        obj.DockCode.GetHashCode() ^ (obj.CarrierArrival.GetHashCode() * 13);
    }

and a IEnumerable

public IEnumerable <Shipments> Shipments
        {
            get
            {
                Debug.Print("Initiated");
                
                foreach (var item in Loads)
                {
                    if (item.ShipTo.Contains(" "))
                    {

                        foreach (var item2 in Routes.Where(d => d.DockCode == item.ShipTo.Substring(0, item.ShipTo.IndexOf(" ")) && d.CarrierDeparture.TimeOfDay == item.ShipTime.TimeOfDay).Distinct(new ShipmentsComparer()))
                        {
                                yield return new Shipments() { Arrival = item2.CarrierArrival, Departure = item2.CarrierDeparture, Issuer = item.Customer, Destination = item.ShipTo, LoadType = item.LoadType };
                        }
                    }
                }
            }
        }

to remove duplicate values but I am still getting duplicates in my item source shown here:

example

How would I get this to only show one of each carrier arrival time?

Upvotes: 2

Views: 64

Answers (1)

Guru Stron
Guru Stron

Reputation: 142213

It seems that you are getting duplicates because you are "distincting" only the inner loop result. You need either to use Distinct on calling side - Shipmetns.Distinct(new ShipmentsComparer()) or if you want to to filter them in the property you can use HashSet:

class ActuallyShipmentsComparer : IEqualityComparer<Shipments>
{
   //your logic
}

    public IEnumerable <Shipments> Shipments
    {
        get
        {
            Debug.Print("Initiated");
            var hash = new HashSet<Shipments>(new ActuallyShipmentsComparer());               
            foreach (var item in Loads)
            {
                if (item.ShipTo.Contains(" "))
                {
                    foreach (var item2 in Routes.Where(d => d.DockCode == item.ShipTo.Substring(0, item.ShipTo.IndexOf(" ")) && d.CarrierDeparture.TimeOfDay == item.ShipTime.TimeOfDay).Distinct(new ShipmentsComparer()))
                    {
                            var shipments = new Shipments { Arrival = item2.CarrierArrival, Departure = item2.CarrierDeparture, Issuer = item.Customer, Destination = item.ShipTo, LoadType = item.LoadType };
                            if(hash.Add(shipments))
                            {
                                yield return shipments;
                            }
                         
                    }
                }
            }
        }
    }

Or try the same with Routes if they are enough to determine shipments equality:

    public IEnumerable<Shipments> Shipments
    {
        get
        {
            Debug.Print("Initiated");
            var hash = new HashSet<Routes>(new ShipmentsComparer()); // rename ShipmentsComparer cause it is actually RoutesComparer             
            foreach (var item in Loads)
            {
                if (item.ShipTo.Contains(" "))
                {
                    foreach (var item2 in Routes.Where(d => d.DockCode == item.ShipTo.Substring(0, item.ShipTo.IndexOf(" ")) && d.CarrierDeparture.TimeOfDay == item.ShipTime.TimeOfDay))
                    {
                        if(hash.Add(item2))
                        {
                            yield return new Shipments { Arrival = item2.CarrierArrival, Departure = item2.CarrierDeparture, Issuer = item.Customer, Destination = item.ShipTo, LoadType = item.LoadType };
                        }                             
                    }
                }
            }
        }
    }

Upvotes: 2

Related Questions