4

I'm wanting to build a for loop that can dynamically handle lists passed into a function for it.

Something along the lines of the following:

public static List<AggregateResult> aggregatePrep(List<sObject> records, Schema.DescribeFieldResult fieldToAggregate)
{
    List<AggregateResult> returnList = new List<AggregateResult>();
    Schema.SObjectType sot = records.getSObjectType();
    SObject sObj = sot.newSObject() ;
    SObjectField sf = fieldToAggregate.getSobjectField();

    for(Schema.SObjectType.getSObjectType(records) so : records)
    {
        returnList.add(so);
        //alternative to above is add(so.sf);
    }
    return returnList;
}

The issues I've run into are as follows:

1) using the for(Schema.SObjectType.getSObjectType(records) so : records) I return the error expecting an equals sign, found '(', so I suspect what I want may not be possible at all.

2) I try referencing sot directly as for(sot s : records) and it states invalid type: sot.

3) The alternative add of (so.sf); returns Field expression not allowed for generic SObject, which is why I would like to find a way to dynamically iterate through a list of matching type for records.

Is there any way to accomplish what I am trying to do? And if not, how should I handle this kind of situation, where I am trying to iterate through a list for items and add it to a different type of list?

Thanks!

2
  • Are you just trying to get the value of that field for every record?
    – Adrian Larson
    Commented Oct 7, 2016 at 20:48
  • @AdrianLarson sort of, I'm wanting to grab the value of that field for every record, and create a List<AggregateResult> I can pass to other functions for doing other calculations on. I would ultimately like to make sure I also carry over the ID of the record the field belongs to as well. (Edit: Updated)
    – Genko
    Commented Oct 7, 2016 at 20:50

1 Answer 1

6

AggregateResult can't be reliably created or modified. They're a construct for querying aggregate data from the database.

Instead, consider using a Map<Id, Object>:

public static Map<Id, Object> extractValues(SObject[] records, SObjectField field) {
  Map<Id, Object> results = new Map<Id, Object>();
  for(SObject record: records) {
    results.put(record.Id, record.get(field));
  }
  return results;
}

You can also build the map ahead of time to get specific subtypes:

public static void extract(Map<Id, Object> values, SObject[] source, SObjectField field) {
  for(SObject record: source) {
    values.put(record.Id, record.get(field));
  }
}

Which you can then do stuff with later:

Map<Id, Decimal> amounts = new Map<Id, Decimal>();
extract(amounts, [SELECT Amount FROM Opportunity], Opportunity.Amount);
3
  • Just curious, I read developer.salesforce.com/docs/atlas.en-us.apexcode.meta/… but am not sure: Is SObject[] different from List<SObject>? You used it in your example, and I was wondering: does using array notation allow you to iterate through a list differently or is there is any added benefits to doing it that way? Are there situations where I should use one vs the other?
    – Genko
    Commented Oct 7, 2016 at 21:17
  • @Genko They're the same thing. It's mostly a habit from decades of using [] to mean an array, but I also rationalize that syntax as being fewer characters (less typing, and we have a 3,000,000 character limit on code), and easier to read in long pieces of code (personal opinion). Use one or other other, as you like, although you should stick to using just one version if you're on a team (e.g. it should be a company decision as which syntax to use, and stick with it).
    – sfdcfox
    Commented Oct 7, 2016 at 21:24
  • This explanation was very helpful, I appreciate it. I used the first example, but am noting all of them. And thank you for answering my other question as well :) This is much cleaner than what I was doing.
    – Genko
    Commented Oct 7, 2016 at 21:31

You must log in to answer this question.

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