slice.js 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041
  1. module.exports = function(arr, start, end, step) {
  2. if (typeof start == 'string') throw new Error("start cannot be a string");
  3. if (typeof end == 'string') throw new Error("end cannot be a string");
  4. if (typeof step == 'string') throw new Error("step cannot be a string");
  5. var len = arr.length;
  6. if (step === 0) throw new Error("step cannot be zero");
  7. step = step ? integer(step) : 1;
  8. // normalize negative values
  9. start = start < 0 ? len + start : start;
  10. end = end < 0 ? len + end : end;
  11. // default extents to extents
  12. start = integer(start === 0 ? 0 : !start ? (step > 0 ? 0 : len - 1) : start);
  13. end = integer(end === 0 ? 0 : !end ? (step > 0 ? len : -1) : end);
  14. // clamp extents
  15. start = step > 0 ? Math.max(0, start) : Math.min(len, start);
  16. end = step > 0 ? Math.min(end, len) : Math.max(-1, end);
  17. // return empty if extents are backwards
  18. if (step > 0 && end <= start) return [];
  19. if (step < 0 && start <= end) return [];
  20. var result = [];
  21. for (var i = start; i != end; i += step) {
  22. if ((step < 0 && i <= end) || (step > 0 && i >= end)) break;
  23. result.push(arr[i]);
  24. }
  25. return result;
  26. }
  27. function integer(val) {
  28. return String(val).match(/^[0-9]+$/) ? parseInt(val) :
  29. Number.isFinite(val) ? parseInt(val, 10) : 0;
  30. }