3

enter image description hereThe following is what my List looks like, it is a web service call that pulls Itinerary data from an external source. There are two passengers for this specific call and I don't need both of their information because its the same flight, how can I remove this extra data?

Test Flight(

ItineraryFlights:[accountCompanions=(), active=true, airline=Delta, arrival=2013-10-12T15:38:00, confirmationNumber=1234565, departure=2013-10-12T12:05:00 , flightNumber=15161, fromAirport=Atlanta, itinerary=null, itineraryDay=2013-10-12T12:05:00, 
itineraryFlightID=3492, status=Active, success=true, toAirport=San Juan], 

ItineraryFlights:[accountCompanions=(), active=true, airline=Delta, arrival=2013-10-12T15:38:00, confirmationNumber=1234565, departure=2013-10-12T12:05:00 , flightNumber=15160, 
fromAirport=Atlanta, itinerary=null, itineraryDay=2013-10-12T12:05:00, itineraryFlightID=3493, status=Active, success=true, toAirport=San Juan], 

ItineraryFlights:[accountCompanions=(), active=true, airline=Delta, arrival=2013-10-12T15:38:00, 
confirmationNumber=1234565, departure=2013-10-12T12:05:00 , flightNumber=15161, fromAirport=Atlanta, itinerary=null, itineraryDay=2013-10-12T12:05:00, itineraryFlightID=3494, status=Active, success=true, toAirport=San Juan], 

ItineraryFlights:[accountCompanions=(), 
active=true, airline=Delta, arrival=2013-10-12T15:38:00, confirmationNumber=1234565, departure=2013-10-12T12:05:00 , flightNumber=15160, fromAirport=Atlanta, itinerary=null, itineraryDay=2013-10-12T12:05:00, itineraryFlightID=3495, status=Active, success=true, 
toAirport=San Juan])

By concatenation of the airline and flight number you can find the dupes and assume all the data underneath it is similar and can be removed. This is what I was thinking for my logic, but I'm unsure now. Am I making this too complicated?

private static List<ServiceBusServices.ItineraryFlights> getFlightInfo(String dryFlyID)
{   
    intineraryFlights = TripProfileProxy.retreiveFlightInformation(dryFlyID);
    Diagnostics.debug('intineraryFlights' + intineraryFlights);
    Integer count = -1;
    String concat;
    String airlines;
    String flightNumber;
    for(ServiceBusServices.ItineraryFlights intinF : intineraryFlights)
    {

        if(count <  0)
        {
            airlines = intinF.airline;
            flightNumber = intinF.flightNumber;
            concat = airlines + ' ' + flightNumber;

        }
        if(intinF.airline + ' ' + intinF.flightNumber == concat)
        {
            intineraryFlights.remove(not sure what do.);
            count + 1;
        }
    }
    return intineraryFlights;
}
2
  • I'm not at all following your logic here. Wouldn't you seem to be looking for the same confirmation number?
    – crmprogdev
    Commented Jun 25, 2015 at 17:03
  • @crmprogdev I could use that also, just on my actual real call out confirmation number is blank, so after some more research and once I can confirm that number will be always be populated I can change it.
    – EricSSH
    Commented Jun 25, 2015 at 17:07

2 Answers 2

2

Simply making a map would suffice. I'd make a custom class to actually hold the key, because simple concatenation might be bad. Here's an implementation.

First, this class should be saved somewhere. I use it pretty much everywhere when I can help it, so I have it as a top-level class, along with NameValuePair, a class that I use for URL parsing/generation.

class KeyPair {
    String key1, key2;
    public KeyPair(String k1, String k2) {
        key1 = k1;
        key2 = k2;
    }
    public Boolean equals(Object other) {
        Keypair kp = (KeyPair)other;
        return kp.key1 == key1 && kp.key2 == key2;
    }
    public Integer hashCode() {
        return System.hashCode(key1+key2);
    }
}

For the actual function, you pretty much just need to use the map against your callout results:

private static List<ServiceBusServices.ItineraryFlights> getFlightInfo(String dryFlyID)
{   
    intineraryFlights = TripProfileProxy.retreiveFlightInformation(dryFlyID);
    Map<KeyPair, ServiceBusServices.ItineraryFlights> flights = new Map<KeyPair, ServiceBusServices.ItineraryFlights>();
    for(ServiceBusServices.ItineraryFlights flight: itineraryFlights) {
        KeyPair kp = new KeyPair(flight.airline, flight.flightNumber);
        if(!flights.containsKey(kp)) {
            flights.put(kp, flight);
        }
    }
    return (intineraryFlights = flights.values());
}
5
  • This looks like a great solution, but because I am not familiar with this type of a solution I'm not sure how to integrate it into what I have currently have.
    – EricSSH
    Commented Jun 25, 2015 at 19:53
  • @EricSSH I broke it up a little better for you. Does this help?
    – sfdcfox
    Commented Jun 25, 2015 at 19:54
  • Look's like it didn't work, it looks like it just moved Delta 1516 to the bottom, updated my question with a screenshot. I understand how you did it now, I may be able to debug
    – EricSSH
    Commented Jun 25, 2015 at 20:03
  • @EricSSH I'm going to have to mock it up. Give me a bit.
    – sfdcfox
    Commented Jun 25, 2015 at 21:35
  • I fixed it, I created a new List and changed my return to return (parsedIntineraryFlights = flights.values()); Thanks
    – EricSSH
    Commented Jun 25, 2015 at 23:15
1

I think you need to do something more like the following:

A list can't contain more than one identical value when performing DML. If you try to add a 2nd value that's identical to it, you could throw a list exception at some point in your code later. So, each time before you add a new value to the list, you run a test to see whether it contains the new value. If it does, you've found a duplicate and can either "break" or add it to a list of dupes so you can continue looking for additional duplicate values.

Another way that would work if you have a unique identifier that you can use as a map key, would be to put the strings into a map and test for whether the map.values() contain the new string value before you add each additional key and string to the map.

If necessary, you could use something as simple as a count integer for the key as that would always be unique for that run through your class. Again, if a dupe was found, you could put it to a different map or add it to a different list, assuming you need to keep track of them (I'm guessing you probably don't).

6
  • Can you elaborate on this statement? "A list can't contain more than one identical value. If you try to add a 2nd value that's identical to it, you'll throw an exception." - I think you're referring to a Set but an exception isn't thrown when an equal item is added to the collection, so I was unsure if it was safe to edit your response with that modification...
    – Mark Pond
    Commented Jun 25, 2015 at 18:28
  • I was thinking in terms of a list of sObject records. If you have two records with the same ID, you'll get a list exception; not necessarily at the point when you add them. So was a comment more in terms of being a preventative measure.
    – crmprogdev
    Commented Jun 25, 2015 at 18:37
  • Yes, makes sense, the exception will be thrown when the DML operation is performed on a list containing duplicates but not when adding to the list itself.
    – Mark Pond
    Commented Jun 25, 2015 at 18:48
  • I've clarified my post so no one will get confused. I think it's a good practice when coding to think ahead for things like that. Try to count the number of posts you've read from people wanting to know what caused the list exception they were getting at the end of their trigger... ;)
    – crmprogdev
    Commented Jun 25, 2015 at 19:09
  • I may be mis understanding your answer, but I am not performing any DML and I don't have a unique key to go off of.
    – EricSSH
    Commented Jun 25, 2015 at 19:19

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .