3

Big picture, upon importing a csv, we have some unique Id's that may be tied to an account already in our instance. I can iterate over a list with no issue and to find any unique Id's with a matching account Id and set it into an existing list. See Below (this is a chopped down version of my code):

public class RegistrationFileUploader
{
   public string csvFile{get;set;}
   public Blob contentCsv{get;set;}
   String[] filelines = new String[]{};
   public List<registration> registrationList {get; set;}
   public Map<integer, Account> accountMap = new Map<integer, Account>();
   public Map<integer, Registration__c> registrationMap = new Map<integer, Registration__c>();
   Set<String> allUniqueIDs = new Set<String>();

   public class Registration {
   public Account acc {get; set;}
   public Registration(Account ac){
           acc = ac;
       }
   }

   public Pagereference ReadCSV()
   {
       if(csvFile!=null){
        csvFile=contentCsv.toString();
        filelines = csvFile.split('\n');
        registrationList = new List<registration>();

        for (Integer i=1; i<filelines.size(); i++)
        {
            String[] inputvalues = new String[]{};
            inputvalues = filelines[i].split(',');

            Account a = new Account();  //account object to be nestled in registration
            if(!String.isBlank(inputvalues[0])){a.LastName = inputvalues[0];}
            if(!String.isBlank(inputvalues[1])){a.FirstName = inputvalues[1];}
            if(!String.isBlank(inputvalues[2])){
                a.uniqueId__c = inputvalues[2];
                allUniqueIDs.add(inputvalues[2]);
            }

            accountMap.put(i,a);
            registrationMap.put(i,r);
            registrationList.add(new cpeRegistration(a));
        } //end of for loop --> (Integer i=1; i<filelines.size(); i++)

        List<Account> uniqueIdMatchAcc = new List<Account>();
        if(allUniqueIDs.size()>0){uniqueIdMatchAcc = [Select id, unique__c From Account Where unique__c in :allUniqueIDs];}   //find any existing accounts by ufid
        if(uniqueIdMatchAcc.size() > 0 ){ //if unique matches were found, feed Id's into registration
           for(Account uma : uniqueIdMatchAcc){
                for(registration crl : registrationList){
                    if(uma.unique__c == crl.acc.unique__c){
                        crl.acc.Id = uma.Id;
                    }
                }
            }
        } 

What I am trying to fix, make a little more bulkified that is, is to do this with maps instead, removing the lists altogether. So instead of the list at the bottom, uniqueIdMatchAcc, I would like that to be a map, and then instead of iterating over a list created from the csv, I would like to iterate over a map. The uniqueIdMatchAccMap would query to see if that unique Id's brings back any account Id's, and if so, I would like to find the matching value in the accountMap, and then add the account Id into the account map. Something like this:

        Map<String,Id> uniqueIdMatchAccMap = new Map<String,Id>();
        //put unique and account id's in a map
        for(Account a: [Select id, unique__c From Account Where unique__c in :allUniqueIDs]){
            uniqueIdMatchAccMap.put(a.unique__c,a.id);
        }
        //This is where I am lost, something like this is what I am looking for though:
 for(Account umam : uniqueIdMatchAccMap){
   for(Account am : accountMap){
   if(umam.unique__c == am.unique__c){am.Id = umam.Id}
   }
 }

I know the above code is the list equivalent of how that works, and is not even close to what the map should look like, however, I am lost on how to look at the fields of one map for matches of another, and then to add one single field into an existing map. Is that even possible, or does everything have to be done with the keys? Thank you in advance for help, it is appreciated.

Working map to list: Still not quite the solution I was looking for, looking for map to map using accountMap not a list, currently registrationList. accountMap is created with the key being the csv line to be able to map accountMap and registrationMap the same. uniqueIdMatchAccMap will not have the same key as accountMap,

        Map<String,Account> uniqueIdMatchAccMap = new Map<String,Account>();         
        for(Account a: [Select unique__c From Account Where unique__c in :allUnique]){
            ufidMatchAccMap.put(a.ufid__c, a);
        }
        for(String unique : uniqueIdMatchAccMap.keySet()){
            for(registration rl : registrationList){
                    if(unique == rl.acc.unique__c){
                        rl.acc.Id = uniqueIdMatchAccMap.get(unique).Id;
                    }
        }

Alright, this iteration works for map to map:

       Map<String, account> uniqueIdMatchAccMap = new Map<String, account>();         
        for(Account a: [Select unique__c From Account Where unique__c in :allUnique]){
            uniqueIdMatchAccMap.put(a.unique__c, a);
        }
        if(uniqueIdMatchAccMap.size() > 0 ){
            for(String unique : uniqueIdMatchAccMap.keySet()){
                for(Integer i : accountMap.keySet()){
                    if(accountMap.get(i).unique__c == unique){
                        accountMap.put(i, uniqueIdMatchAccMap.get(unique));
                    }
                }
            }
        }

Is this any better than my original list to list iteration though as far as governor limits are concerned?

2 Answers 2

1

To map them by Unique Id for later use:

Map<String, Account> existingAccounts = new Map<String, Account>();
for (Account existingAccount : [
    SELECT Unique__c FROM Account
    WHERE Unique__c IN :allUniqueIds
]){
    existingAccounts.put(existingAccount.Unique__c, existingAccount);
}

Then when iterating through you can retrieve them by that value.

String uniqueId = registration.account.Unique__c;
if (existingAccounts.containsKey(uniqueId))
    registration.account.Id = existingAccounts.get(uniqueId).Id;
3
  • Ok, I have the existingAccounts found from the soql query mapped. Iterating through through the accountMap, putting found accounts from the new existingAccoutnts Map into accountMap is where I am confused. The uniqueId will be in accountMap, as a value, not a key. Your iteration looks like it is looping through a list, correct? I want to make that the accountMap that it is iterating though, putting the account Id into the accountMap. Is this possible when the key is not the same in accountMap (key is csv line)? Feb 7, 2016 at 16:55
  • Uh, the syntax is Map.put(key, value). Hence Unique Id is the key, the Account record itself is the value.
    – Adrian Larson
    Feb 7, 2016 at 19:47
  • Ok, I put the code example at the bottom of my original question. I am looking to completely replace registrationList, and instead use accountMap that was made when the csv was created. This will have a different key than the new uniqueIdMatchAccMap. How do I search the variables in the accountMap for the key that is in the uniqueIdMatchAccMap, and then assign the variable from uniqueIdMatchAccMap into the accountMap as a new variable? Feb 7, 2016 at 20:14
0

I think I understand your requirement now. I'm assuming that the line number being the key is useful later, so I'm just going to ignore accountMap and make a new one to do what you're trying to do.

Map<String, Account> uniqueIDAccountMap = new Map<String, Account>();

//at the end of the CSV Read loop
uniqueIDAccountMap.put(a.uniqueID__c, a);

if (uniqueIDAccountMap.size() > 0)
{
    for (Account acc : [select ID, uniqueID__c from Account where UniqueID__c in :uniqueIDAccountMap.KeySet()])
    {
        uniqueIDAccountMap.get(acc.uniqueID__c).ID = acc.ID;
    }
}

Since both uniqueIDAccountMap and accountMap are storing references to the same account object, this means that this actually updates accountMap as well (and takes up minimal extra space).

2
  • This is the error I am getting: Incompatible key type String for Map<Integer,Account>. This is because my key value in the accountMap is not the same keys as in uniqueIdMatchAccMap, the keys for accountMap are made by the line numbers of the csv, I need them to be the same as the registrationMap. What I am looking to do, is to take the uniqueId found the uniqueIdMatchAccMap, and if it finds that uniqueId in the already created accountMap values, then to insert the account Id that belongs to that account found on the query. Sorry for the long convoluted answer, I hope you follow me? Feb 7, 2016 at 16:37
  • @NicMcBride I've updated the answer, hopefully this is what you are looking for. Feb 7, 2016 at 20:27

You must log in to answer this question.

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