3

I created a generic sorting utility using the comparable interface to test sorting by product name:

public class GenericSortingUtil {

public virtual class ObjWrapper implements Comparable {

    public sObject obj;

    public ObjWrapper() {}

    public ObjWrapper(Sobject obj) {
        this.obj = obj;

    }

    public virtual Integer compareTo(Object compareTo) {

        ObjWrapper compareToObj = (ObjWrapper)compareTo;

        if((String)obj.get('Name') > (String)compareToObj.obj.get('Name')) {
            return 1;
        }

        if((String)obj.get('Name') == (String)compareToObj.obj.get('Name')) {
            return 0;
        }

        return -1;
    }
}     

public static List<ObjWrapper> getProducts() {
    List<ObjWrapper> results = new List<ObjWrapper>();

    for (Product2 p : [select Name, ProductCode, Size__c from Product2 limit 100]) {
        results.add(new ObjWrapper(p));
    }
    return results;
} 
}

Child classs:

public class ShirtWrapper extends GenericSortingUtil.ObjWrapper {   

public override Integer compareTo(Object compareTo) {

    ShirtWrapper compareToObj = (ShirtWrapper)compareTo;

    integer nameOrder = super.compareTo(compareTo);
    return nameOrder == 0 ? getSizeOrder(String.valueOf(obj.get('Size__c'))) - getSizeOrder(String.valueOf(compareToObj.obj.get('Size__c'))) : nameOrder;
}   


public Integer getSizeOrder(string size) {
    Integer retval = -1;
    switch on size {
        when 'S' {
            retval = 0;
        } 
        when 'M' {
            retval = 1;
        }
        when 'L' {
            retval = 2;
        }
        when 'XL' {
            retval= 3;
        }
        when else {
            return retval;
        }
    }
    return retval;
}       
}

I can run the code in the anonymous window and get the correct results:

List<GenericSortingUtil.ObjWrapper> results = GenericSortingUtil.getProducts();
results.sort();
for(GenericSortingUtil.ObjWrapper ow : results) {
system.debug('********************* ' + ow.obj.get('Name'));
}

I'm trying to determine how I can sort by two fields so that each product grouping can be sorted by size. The products are clothing items. Each product has a series of sizes. For simplicity, the sizes are S, M, L, XL. What I am trying to achieve is sort by the size field as well as the product name.

For example, if I have the following products: black.v-neck.s, black.v-neck.m, black.v-neck.l, and black.v-neck.xl. I would want them sorted by smallest to largest:

black.v-neck.s black.v-neck.m black.v-neck.l black.v-neck.xl

There is a size__c field for each product that holds the size value.

Any feedback on how to sort by a second field (size) so I can keep each product group in the proper order by size would be appreciated.

3

I think your best bet is going to be to extend your existing class, and implement the extra logic in the child class.

public class ShirtWrapper extends ObjWrapper{

    public Integer compareTo(Object compareTo) {

        ShirtWrapper compareToObj = (ShirtWrapper)compareTo;

        integer nameOrder = super.compareTo(compareTo);
        return nameOrder == 0 ? 
           getSizeOrder(String.valueOf(obj.get('Size__c'))) - getSizeOrder(String.valueOf(compareToObj.get('Size__c')))
           : nameOrder;

    }

    public static integer getSizeOrder(string size){
        switch on size {
            when 'S'{ return 0;}
            when 'M'{ return 1;}
            when 'L'{ return 2;}
            when 'XL'{ return 3;}
            when else{ throw new BadSizeException();}
            //I haven't tested whether the compiler will complain this doesn't always return,
            //if it does you can move the throw to the bottom of the method.
    }
}
| improve this answer | |
  • 3
    switch on uses when and when else to avoid collision with existing sObject names. – David Reed Jun 10 '18 at 18:37
  • @DavidReed Corrected, I only heard they implemented switch yesterday and I'm eager to start using it on Monday. – IllusiveBrian Jun 11 '18 at 1:12
  • Hi @DavidReed, thanks for the example. I included the modified code above. I made the ObjWrapper class virtual so I could extend it in the ShirtWrapper class and I made the compareTo method virtual so I could override it. Is this the correct implementation you were indicating? I am trying to run the code in the anonymous window, but do I need to pass the results from the ObjWrapper sort into the ShirtWrapper? – Dman100 Jun 11 '18 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.