Skip to content

Instantly share code, notes, and snippets.

@jamessimone
Last active April 8, 2024 09:27
Show Gist options
  • Save jamessimone/fd8f24fd1cbe76f18983cb0f20a2d92e to your computer and use it in GitHub Desktop.
Save jamessimone/fd8f24fd1cbe76f18983cb0f20a2d92e to your computer and use it in GitHub Desktop.
Helper methods for working with collections in Apex
public class CollectionUtils {
public static List<Id> convertToIdList(List<SObject> sObjectList) {
return new List<Id>(convertToIdSet(sObjectList));
}
public static List<Id> convertToIdList(List<SObject> sObjectList, SObjectField field) {
return convertToIdList(sObjectList, string.valueOf(field));
}
public static List<Id> convertToIdList(List<SObject> sObjectList, string field) {
List<Id> returnList = new List<Id>();
for(SObject o : sObjectList) {
returnList.add((Id) o.get(field));
}
return returnList;
}
public static Set<Id> convertToIdSet(List<SObject> sObjectList, SObjectField field) {
return new Set<Id>(convertToIdList(sObjectList, string.valueOf(field)));
}
public static Set<Id> convertToIdSet(List<SObject> sObjectList, string field) {
return new Set<Id>(convertToIdList(sObjectList, field));
}
public static Set<Id> convertToIdSet(List<SObject> sObjectList) {
return new Set<Id>(convertToMap(sObjectList).keySet());
}
public static Set<String> convertToStringSet(List<SObject> sObjectList, SObjectField filterField) {
Set<String> strings = new Set<String>();
for(SObject record : sObjectList) {
strings.add((String) record.get(filterField));
}
return strings;
}
public static Map<String, SObject> convertToStringKeyMap(List<SObject> sObjectList, SObjectField filterField) {
Map<String, SObject> stringMap = new Map<String, SObject>();
for(SObject record : sObjectList) {
stringMap.put((String) record.get(filterField), record);
}
return stringMap;
}
public static Map<Id,SObject> convertToMap(List<SObject> sObjectList) {
return sObjectList.isEmpty() ? new Map<Id,SObject>() : new Map<Id,SObject>(sObjectList);
}
public static Map<Id, SObject> convertToMap(List<SObject> sObjectList, SObjectField field) {
return convertToMap(sObjectList, string.valueOf(field));
}
public static Map<Id, SObject> convertToMap(List<SObject> sObjectList, String fieldName) {
Map<Id,SObject> mapping = new Map<Id,SObject>();
if(sObjectList.isEmpty() == false) {
SObjectType sObjectType = sObjectList[0].getSObjectType();
if(sObjectType.getdescribe().fields.getmap().containsKey(fieldName)) {
//Validation to make sure fieldName is an Id or Lookup
Set<String> acceptedFieldTypes = new Set<String>{'STRING','ID','REFERENCE', 'DATACATEGORYGROUPREFERENCE'};
String sObjectField = String.valueOf(sObjectType) + '.' + fieldName;
if(!acceptedFieldTypes.contains(DescribeUtils.getFieldType(sObjectField))) {
throw new Exceptions.DescribeException('Field should be of type Id');
} else {
for(SObject sObj : sObjectList) {
if(sObj.get(fieldName) == null) continue;
mapping.put((Id)sObj.get(fieldName), sObj);
}
}
}
}
return mapping;
}
public static Map<Id, Object> convertToMap(List<Object> objects, String keyFieldName) {
// avoid costly serialization/de-serialization if it's anything other than a generic object
if(objects instanceof List<SObject>) {
return convertToMap((List<SObject>) objects, keyFieldName);
}
Map<Id, Object> keyFieldToObjects = new Map<Id, Object>();
for(Object obj : objects) {
Map<String, Object> deserializedObj = (Map<String, Object>)JSON.deserializeUntyped(JSON.serialize(obj));
if(deserializedObj.containsKey(keyFieldName)) {
Id fieldVal = (Id)deserializedObj.get(keyFieldName);
if(String.isNotBlank(fieldVal)) {
keyFieldToObjects.put(fieldVal, obj);
}
}
}
return keyFieldToObjects;
}
public static Map<Id, Id> convertToIdMap(List<SObject> sObjectList, SObjectField idKey, SObjectField idValue) {
Map<Id, Id> resultMap = new Map<Id, Id>();
for(SObject sObj : sObjectList) {
if(sObj.get(idKey) == null) continue;
resultMap.put((Id)sObj.get(idKey), (Id)sObj.get(idValue));
}
return resultMap;
}
public static Map<String, List<SObject>> convertToListMap(List<SObject> sObjectList, SObjectField idKey) {
return convertToListMap(sObjectList, idKey.getDescribe().getName(), null);
}
public static Map<String, List<SObject>> convertToListMap(List<SObject> sObjectList, String idKey) {
return convertToListMap(sObjectList, idKey, null);
}
public static Map<String, List<SObject>> convertToListMap(List<SObject> sObjectList, SObjectField idKey, CollectionEvaluator eval) {
return convertToListMap(sObjectList, idKey.getDescribe().getName(), eval);
}
public static Map<String, List<SObject>> convertToListMap(List<SObject> sObjectList, String idKey, CollectionEvaluator eval) {
Map<String, List<SObject>> keyToListValues = new Map<String, List<SObject>>();
for(SObject sObj : sObjectList) {
String key = (String)sObj.get(idKey);
if(String.isBlank(key) || eval != null && eval.matchesCriteria(sObj) == false) { continue; }
else if(keyToListValues.containsKey(key)) {
keyToListValues.get(key).add(sObj);
} else {
keyToListValues.put(key, new List<SObject>{ sObj });
}
}
return keyToListValues;
}
public abstract class CollectionEvaluator {
public abstract Boolean matchesCriteria(SObject obj);
}
public static Set<String> removeStringsFromStringSet(Set<String> source, Set<String> eliminate) {
Set<String> excludedSet = new Set<String>(source);
excludedSet.removeAll(eliminate);
return excludedSet;
}
public static Map<String, SObject> convertToStringMapLowercase(List<SObject> sObjectList, String fieldName) {
Map<String,SObject> mapping = new Map<String,SObject>();
for(SObject sObj : sObjectList) {
if(sObj.get(fieldName) != null) {
mapping.put(((String)sObj.get(fieldName)).toLowerCase(), sObj);
}
}
return mapping;
}
public static Boolean isNullOrEmpty(List<Object> listOfThings) {
return listOfThings == null || listOfThings.isEmpty();
}
public static Boolean isNullOrEmpty(Map<String,String> mapOfThings) {
return mapOfThings == null || mapOfThings.isEmpty();
}
public static SObject getFirstOrDefault(List<SObject> listOfThings) {
return listOfThings.isEmpty() ? null : listOfThings[0];
}
public static List<SObject> removeAll(List<SObject> records, Set<Id> idMatches, SObjectField matchField) {
List<SObject> reducedList = new List<SObject>();
for(SObject record : records) {
if(idMatches.contains((Id)record.get(matchField)) == false) {
reducedList.add(record);
}
}
return reducedList;
}
public static List<SObject> getRecordsMatchingType(List<SObject> records, Schema.SObjectType sObjectType) {
List<SObject> matchingRecords = DescribeUtils.createSObjectList(sObjectType);
for (SObject record : records) {
if(record.getSObjectType() == sObjectType) {
matchingRecords.add(record);
}
}
return matchingRecords;
}
public static SObject getFirstOrDefaultOfType(List<SObject> records, Schema.SObjectType sObjectType){
return getFirstOrDefault(getRecordsMatchingType(records, sObjectType));
}
private static string fieldName(SObjectField fieldObject) {
return fieldObject.getDescribe().getName();
}
private static Set<String> fieldNames(List<SObjectField> fieldObjectList) {
Set<String> fieldStrings = new Set<String>();
for(SObjectField fieldObject : fieldObjectList) {
fieldStrings.add(fieldName(fieldObject));
}
return fieldStrings;
}
public static Set<String> getFieldNamesFromFieldSet(FieldSet fs) {
Set<String> fields = new Set<String>();
for(FieldSetMember member : fs.getFields()) {
fields.add(member.getFieldPath().toLowerCase());
}
return fields;
}
public static Set<String> getFieldLabelsFromFieldSet(FieldSet fs) {
Set<String> fields = new Set<String>();
for(FieldSetMember member : fs.getFields()) {
fields.add(member.getLabel());
}
return fields;
}
public static List<SObject> getUpdatedRecordsWithChangedField(List<SObject> records, Map<Id, SObject> oldRecordMap, SObjectField field) {
return getUpdatedRecordsWithChangedFields(records, oldRecordMap, new Set<String> { fieldName(field) });
}
public static List<SObject> getUpdatedRecordsWithChangedField(List<SObject> records, Map<Id, SObject> oldRecordMap, String field) {
return getUpdatedRecordsWithChangedFields(records, oldRecordMap, new Set<String> { field });
}
public static List<SObject> getUpdatedRecordsWithChangedFields(List<SObject> records, Map<Id, SObject> oldRecordMap, List<SObjectField> fields) {
return getUpdatedRecordsWithChangedFields(records, oldRecordMap, fieldNames(fields));
}
public static List<SObject> getUpdatedRecordsWithChangedFields(List<SObject> records, Map<Id, SObject> oldRecordMap, Set<String> fields) {
List<SObject> updatedRecords = new List<SObject>();
List<String> fieldsList = new List<String>(fields);
for(SObject record : records) {
SObject oldRecord = oldRecordMap.get(record.Id);
if(hasChangeBasedOnFields(record, oldRecord, fieldsList)) {
updatedRecords.add(record);
}
}
return updatedRecords;
}
public static Boolean hasChangeBasedOnFields(SObject current, SObject old, List<String> fields) {
Boolean hasChange = false;
Integer index = 0;
while(index < fields.size() && !hasChange) {
String fieldName = fields[index];
if(current.get(fieldName) != old.get(fieldName)) {
hasChange = true;
}
index++;
}
return hasChange;
}
}
@jamessimone
Copy link
Author

Updated with generic Map<Id, Object> convertToMap method

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment