[SalesForce] Dynamically get the Map of “DataType” and all “Fields”

I want to dynamically get the Map of "DataType" and all "Fields" associated with that data type . I`m trying below, but keep getting full list of the fields. I ONLY need a map where "DataType" will match "Fields". For example, please see desired Map below. When I manually create this map, it works fine but I need this map dynamically. Im using new
Map>(); to hold list of "DataType" and ALL associated "Fields" but it keeps failing. Please point me in right direction.

DataTypeMap = new Map<String, Set<String>>();
     TypeSet = new Set<String>();

    String objType='Account' ;
    Map<String, Schema.SObjectType> schemaMap = Schema.getGlobalDescribe();
    Schema.SObjectType leadSchema = schemaMap.get(objType);
    Map<String, Schema.SObjectField> fieldMap = leadSchema.getDescribe().fields.getMap();

    for (String fieldName: fieldMap.keySet()) {
        //get all the fields label for Account Object
        String fieldLabel = fieldMap.get(fieldName).getDescribe().getLabel();
        TypeSet.add(fieldLabel);
        //get data types for each fields
        Schema.DisplayType fielddataType = fieldMap.get(fieldName).getDescribe().getType();

        DataTypeMap.put(String.valueof(fielddataType), TypeSet);
    }

desired Output (example of how I need the Map) –

DataTypeMap.put('STRING', new
Set{'-None-','Name','AccountNumber','Site','Jigsaw','SicDesc'});
DataTypeMap.put('PICKLIST', new Set{'-None-','AccountSource','Industry','Ownership','Rating');
DataTypeMap.put('TEXTAREA', new Set{'-None-','Description','Message__c'});
DataTypeMap.put('BOOLEAN', new Set{'-None-','isCreated','isDeleted'});
DataTypeMap.put('REFERENCE', new Set{'-None-','ParentId','MyObject__c'});
DataTypeMap.put('DATETIME', new Set{'-None-','Meeting_date__C','Expiry__c'});
DataTypeMap.put('DATE', new Set{'-None-','Date__1','date__2'});
DataTypeMap.put('INTEGER', new Set{'-None-','Number_of_Seats__c','Number_of_Cities__c'});

Best Answer

You can dramatically simplify your logic here. Most often, this kind of accumulation workflow follows a standard "skeleton" where you check whether the Map contains a Set or List for a given key, add the collection if it does not, and then add the data point to the collection for the key. (In Python and some other languages, this is called a multidict, a map or dictionary where each key has multiple values).

Here's an example of what it could look like in your case. If you want the labels sorted, you'll need to use a List rather than a Set, and add the '--None--' entries yourself.

for (String fieldName: fieldMap.keySet()) {
    Set<String> TypeSet;
    Schema.DisplayType fielddataType = fieldMap.get(fieldName).getDescribe().getType();
    String fieldLabel = fieldMap.get(fieldName).getDescribe().getLabel();

    if (!DataTypeMap.containsKey(String.valueof(fielddataType)) {
        DataTypeMap.put(String.valueof(fielddataType), new Set<String>());
    }

    DataTypeMap.get(String.valueof(fielddataType)).add(fieldLabel);
}

As a side note, using the field label may be problematic later, as they're not unique like the API name.

Related Topic