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.

1 Answer 1

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.
    }
}
3
  • 3
    switch on uses when and when else to avoid collision with existing sObject names.
    – David Reed
    Jun 10, 2018 at 18:37
  • @DavidReed Corrected, I only heard they implemented switch yesterday and I'm eager to start using it on Monday. Jun 11, 2018 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, 2018 at 17:09

You must log in to answer this question.

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