There's already some good answers here, but I figured I'd throw my hat into the ring anyways.
In my approach, I've tried to stay as close to the Javascript versions as possible.
The JS slice
is a variable arity function that makes use of up to the first two arguments it is provided, so I provided three methods for my Slice
class with 0, 1, and 2 parameters respectively.
Also, JS doesn't have integers, and all numbers are floating point, so I defined my method parameters as Decimal
s, and rounded with them the CEILING
round mode; meaning that -0.5
is taken to be 0
.
I wanted to name the parameters begin
and end
to stay inline with the mdn page, but those are unfortunately reserved (for future use) keywords.
I also went with a more OO approach instead of using static utility methods, but that should be easy enough to change if you want to do it the other way instead.
public class Slice {
private list<Object> olist;
public Slice(list<Object> olist){
this.olist = olist;
}
public list<Object> slice(){
return olist.clone();
}
public list<Object> slice(Decimal x_begin){
Integer start = x_begin == NULL ? 0 : (Integer) x_begin.round(System.RoundingMode.CEILING);
return commonSlice(start,olist.size());
}
public list<Object> slice(Decimal x_begin, Decimal x_end){
Integer start = x_begin == NULL ? 0 : (Integer) x_begin.round(System.RoundingMode.CEILING);
Integer finish = x_end == NULL ? olist.size() : (Integer) x_end.round(System.RoundingMode.CEILING);
return commonSlice(start, finish);
}
private list<Object> commonSlice(Integer x_begin, Integer x_end){
list<Object> ret = new list<Object>();
x_begin = x_begin < 0 ? olist.size() + x_begin : x_begin ;
x_end = x_end < 0 ? olist.size() + x_end : x_end ;
Integer maxIndex = olist.size();
while (x_begin < maxIndex && x_begin < x_end){
ret.add(olist[x_begin]);
x_begin++;
}
return ret;
}
}
Some examples:
list<Integer> ilist = new list<Integer>{1,2,3,4,5};
Slice s = new Slice(ilist);
system.debug(s.slice()); // (1, 2, 3, 4, 5)
system.debug(s.slice(-.5,20)); // (1, 2, 3, 4, 5)
system.debug(s.slice(.5)); // (2, 3, 4, 5)
system.debug(s.slice(1)); // (2, 3, 4, 5)
system.debug(s.slice(2,-2)); // (3)
system.debug(s.slice(2,-3)); // ()
system.debug(s.slice(7,100)); // ()
system.debug(s.slice(NULL,2)); // (1, 2)
slice
method call?temp[i-startIndex] = ary[i];
adrian - I added bounds checking so that it was compariable with sfdcfox's version (not that this mattered really, the time is all in the loop anyway. Adrian median time was about 15ms and Sfdc median time was 23ms. Thanks again!!