2

My current data in a List of custom data type :

Name      City  Email      Phone  Plan

Jessica   NY    A@cnn.com  5454   Gold
Hannah    SF    H@cnn.com  2323   Silver
Jessica   NY    A@cnn.com  5454   Bronze
Clay      LA    C@cnn.com  7678   Bronze
Hannah    SF    H@cnn.com  2323   Gold

How I want :

Name      City  Email      Phone  Plan

Jessica   NY    A@cnn.com  5454   Gold;Bronze
Hannah    SF    H@cnn.com  2323   Silver;Gold
Clay      LA    C@cnn.com  7678   Bronze

i.e records having same Name/City/Email/Phone be grouped together .

Trial - I have created a map Name+City+Email+Phone as key .

Any example on how to proceed and if this can be concatenated with ; ? List is obtained by parsing xml response from a callout

Updated :

If(AccountList != null && AccountList.size() > 0) {                           
  for(ClassName.InnerClassObject myRec :AccountList){


    String tempKey = myRec.Name + myRec.Role + myRec.Email + myRec.Phone;

      if(AccountTeamMap.containsKey(tempKey)) {
         AccountTeamMap.put(tempKey,AccountTeamMap.get(tempKey) + ';' + myRec.Product);                           


       }
        else
           {
            AccountTeamMap.put(tempKey,myRec.Product);

           }

       } 


      List<ClassName.InnerClassObject> mergedProductsContacts = new List<ClassName.InnerClassObject>();

                    for(String accTeamKey : AccountTeamMap.keySet()){
                        ClassName.InnerClassObject tempCuctCon = new ClassName.InnerClassObject();
                        List<String> splitKey = accTeamKey.Split('-');
                        tempCuctCon.Name = splitKey[0];
                        tempCuctCon.Role = splitKey[1];
                        tempCuctCon.Email = splitKey[2];
                        tempCuctCon.Phone = splitKey[3];
                        tempCuctCon.Product = AccountTeamMap.get(accTeamKey);
                        mergedProductsContacts.add(tempCuctCon);
                    }


                    response.NewAccountList = mergedProductsContacts;   
  • why not just add the list to the set? set do not allow dupes raydehler.com/cloud/clod/apex-convert-from-list-to-set-and-vice-versa.html – Rao Jun 6 '17 at 18:26
  • The page is not available . Also , will that help my cause ? – SFDCRookie Jun 6 '17 at 18:32
3

This is my approach without double looping and String.join()

Map<String, String> finalMap = new Map<String, String>();

for(MyClass myRec :inputDataList){

    String tempKey = myRec.Name + myRec.City + myRec.Email + myRec.Phone;
    //check key exists 
    if(finalMap.containsKey(tempKey))
    {
        //take previous value and append ';' before putting current value
        finalMap.put(tempKey,finalMap.get(tempKey) + ';' + myRec.Plan);
    }
    else
    {
        finalMap.put(tempKey,myRec.Plan);
    }
}

Update

You are looping through the keys and splitting like this at your updated code.

List<String> splitKey = accTeamKey.Split('-');

Since you are parsing the key based on '-' so update this line as follows:

String tempKey = myRec.Name + '-' + myRec.Role + '-' + myRec.Email + '-' + myRec.Phone;

As, your current code key is not getting concatenated by '-', that's why the error is.

  • Hi Shantanu . Thanks for your help . I updated my code accordingly and now I want to assign the map of string/string to a list of same type as before . i.e of object type InnerClassObject . Can you please take a look at the updated section ? I am getting null pointer exception. – SFDCRookie Jun 29 '17 at 16:52
3

From where you are right now, the easiest route is probably to have your map, keyed on the combination of Name, City, Email, and Phone, store a List<String> as its value.

The nice thing about storing your Plan values in a List<String> is that you'll be able to get your desired output using String.Join(List<String> input, String glue)

Some brief example code

Map<String, List<String>> myMap = new Map<String, List<String>>();
String tempKey;

for(MyClass myRec :inputDataList){
    // I use a temp variable here because it saves a bit of typing
    tempKey = myRec.Name + myRec.City + myRec.Email + myRec.Phone;

    // Using this pattern to break up instantiating/populating an empty map
    //   also saves a bit of typing.
    // Ignoring the fact that we could immediately place the first value into the new
    //   list means we don't need an ELSE block to handle every record but the first
    //   (the first for each key, at least).
    if(!myMap.containsKey(tempKey)){
        myMap.put(tempKey, new List<String>());
    }

    myMap.get(tempKey).add(myRec.Plan);
}

// We need one more loop to finish consolidating your Plan values
for(String mapKey :myMap.keySet()){
    // The 'glue' string here is simply a semicolon
    // String.join(['gold', 'silver'], ';') yields 'gold;silver'
    // With String.join, you don't need to worry about extra semicolons appearing
    //   at the start or end of your string 
    String consolidated = String.join(myMap.get(mapKey), ';');

    // I'll leave putting the consolidated value into the appropriate record to you.
    // Perhaps you'll have another map where the same composite key (mapKey) stores
    //   an SObject instance
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.