0

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'});

2 Answers 2

0

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.

1
  • @sfdcfox and David Reed.. Thank you both! I was able to resolve it.
    – Wendy
    Commented Apr 22, 2018 at 10:02
1

Here's a generic method that can get a Map of fields by display type:

public Map<DisplayType, SObjectField[]> getFieldsByTypeForSObject(SobjectType st) {
    Map<DisplayType, SObjectField[]> fieldsByType = new Map<DisplayType, SObjectField[]>();
    for(DisplayType dt: DisplayType.values()) {
        fieldsByType.put(dt, new SObjectField[0]);
    }
    for(SObjectField field: st.getDescribe().fields.getMap().values()) {
        fieldsByType.get(field.getDescribe().getType()).add(field);
    }
    for(DisplayType dt: DisplayType.values()) {
        if(fieldsByType.get(dt).isEmpty()) {
            fieldsByType.remove(dt);
        }
    }
    return fieldsByType;
}

I generally prefer to work with raw types instead of strings, but you wanted strings:

public Map<String, String[]> getFieldsByTypeForSObject(String st) {
    Map<String, String[]> fieldsByType = new Map<String, String[]>();
    for(DisplayType dt: DisplayType.values()) {
        fieldsByType.put(dt.name(), new String[0]);
    }
    for(SObjectField field: Schema.getGlobalDescribe().get(st).getDescribe().fields.getMap().values()) {
        fieldsByType.get(field.getDescribe().getType().name()).add(String.valueOf(field));
    }
    for(DisplayType dt: DisplayType.values()) {
        if(fieldsByType.get(dt.name()).isEmpty()) {
            fieldsByType.remove(dt.name());
        }
    }
    return fieldsByType;
}

You must log in to answer this question.

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