Permalink
Browse files

feat(limitTo): extend the filter to take a beginning index argument

Extend the limitTo filter to take an optional argument for beginning index.
It provides a slice-alike functionality to manipulate the input.

Closes #5355
Closes #10899
  • Loading branch information...
1 parent 49b54b0 commit aaae3cc4160417e6dad802ed9d9f6d5471821a87 @tameraydin tameraydin committed with pkozlowski-opensource Mar 9, 2014
Showing with 81 additions and 2 deletions.
  1. +15 −2 src/ng/filter/limitTo.js
  2. +66 −0 test/ng/filter/limitToSpec.js
@@ -17,6 +17,8 @@
* If the number is negative, `limit` number of items from the end of the source array/string
* are copied. The `limit` will be trimmed if it exceeds `array.length`. If `limit` is undefined,
* the input will be returned unchanged.
+ * @param {string|number} begin Index at which to begin limitation. As a negative index, `begin`
+ * indicates an offset from the end of `input`. Defaults to `0`.
* @returns {Array|string} A new sub-array or substring of length `limit` or less if input array
* had less than `limit` elements.
*
@@ -88,7 +90,7 @@
</example>
*/
function limitToFilter() {
- return function(input, limit) {
+ return function(input, limit, begin) {
if (Math.abs(Number(limit)) === Infinity) {
limit = Number(limit);
} else {
@@ -99,6 +101,17 @@ function limitToFilter() {
if (isNumber(input)) input = input.toString();
if (!isArray(input) && !isString(input)) return input;
- return limit >= 0 ? input.slice(0, limit) : input.slice(limit);
+ begin = (!begin || isNaN(begin)) ? 0 : toInt(begin);
+ begin = (begin < 0 && begin >= -input.length) ? input.length + begin : begin;
+
+ if (limit >= 0) {
+ return input.slice(begin, begin + limit);
+ } else {
+ if (begin === 0) {
+ return input.slice(limit, input.length);
+ } else {
+ return input.slice(Math.max(0, begin + limit), begin);
+ }
+ }
};
}
@@ -23,6 +23,19 @@ describe('Filter: limitTo', function() {
expect(limitTo(number, '3')).toEqual("100");
});
+ it('should return the first X items beginning from index Y when X and Y are positive', function() {
+ expect(limitTo(items, 3, '3')).toEqual(['d', 'e', 'f']);
+ expect(limitTo(items, '3', 3)).toEqual(['d', 'e', 'f']);
+ expect(limitTo(str, 3, 3)).toEqual("wxy");
+ expect(limitTo(str, '3', '3')).toEqual("wxy");
+ });
+
+ it('should return the first X items beginning from index Y when X is positive and Y is negative', function() {
+ expect(limitTo(items, 3, '-3')).toEqual(['f', 'g', 'h']);
+ expect(limitTo(items, '3', -3)).toEqual(['f', 'g', 'h']);
+ expect(limitTo(str, 3, -3)).toEqual("xyz");
+ expect(limitTo(str, '3', '-3')).toEqual("xyz");
+ });
it('should return the last X items when X is negative', function() {
expect(limitTo(items, -3)).toEqual(['f', 'g', 'h']);
@@ -33,6 +46,19 @@ describe('Filter: limitTo', function() {
expect(limitTo(number, '-3')).toEqual("045");
});
+ it('should return the last X items until index Y when X and Y are negative', function() {
+ expect(limitTo(items, -3, '-3')).toEqual(['c', 'd', 'e']);
+ expect(limitTo(items, '-3', -3)).toEqual(['c', 'd', 'e']);
+ expect(limitTo(str, -3, -3)).toEqual("uvw");
+ expect(limitTo(str, '-3', '-3')).toEqual("uvw");
+ });
+
+ it('should return the last X items until index Y when X is negative and Y is positive', function() {
+ expect(limitTo(items, -3, '4')).toEqual(['b', 'c', 'd']);
+ expect(limitTo(items, '-3', 4)).toEqual(['b', 'c', 'd']);
+ expect(limitTo(str, -3, 4)).toEqual("uvw");
+ expect(limitTo(str, '-3', '4')).toEqual("uvw");
+ });
it('should return an empty array when X = 0', function() {
expect(limitTo(items, 0)).toEqual([]);
@@ -60,6 +86,18 @@ describe('Filter: limitTo', function() {
expect(limitTo(str, undefined)).toEqual(str);
});
+ it('should take 0 as beginning index value when Y cannot be parsed', function() {
+ expect(limitTo(items, 3, 'bogus')).toEqual(limitTo(items, 3, 0));
+ expect(limitTo(items, -3, 'null')).toEqual(limitTo(items, -3));
+ expect(limitTo(items, '3', 'undefined')).toEqual(limitTo(items, '3', 0));
+ expect(limitTo(items, '-3', null)).toEqual(limitTo(items, '-3'));
+ expect(limitTo(items, 3, undefined)).toEqual(limitTo(items, 3, 0));
+ expect(limitTo(str, 3, 'bogus')).toEqual(limitTo(str, 3));
+ expect(limitTo(str, -3, 'null')).toEqual(limitTo(str, -3, 0));
+ expect(limitTo(str, '3', 'undefined')).toEqual(limitTo(str, '3'));
+ expect(limitTo(str, '-3', null)).toEqual(limitTo(str, '-3', 0));
+ expect(limitTo(str, 3, undefined)).toEqual(limitTo(str, 3));
+ });
it('should return input if not String or Array or Number', function() {
expect(limitTo(null, 1)).toEqual(null);
@@ -99,4 +137,32 @@ describe('Filter: limitTo', function() {
expect(limitTo(str, -Infinity)).toEqual(str);
expect(limitTo(str, '-Infinity')).toEqual(str);
});
+
+ it('should return an empty array if Y exceeds input length', function() {
+ expect(limitTo(items, '3', 12)).toEqual([]);
+ expect(limitTo(items, 4, '-12')).toEqual([]);
+ expect(limitTo(items, -3, '12')).toEqual([]);
+ expect(limitTo(items, '-4', -12)).toEqual([]);
+ });
+
+ it('should return an empty string if Y exceeds input length', function() {
+ expect(limitTo(str, '3', 12)).toEqual("");
+ expect(limitTo(str, 4, '-12')).toEqual("");
+ expect(limitTo(str, -3, '12')).toEqual("");
+ expect(limitTo(str, '-4', -12)).toEqual("");
+ });
+
+ it('should return the entire string beginning from Y if X is positive and X+Y exceeds input length', function() {
+ expect(limitTo(items, 7, 3)).toEqual(['d', 'e', 'f', 'g', 'h']);
+ expect(limitTo(items, 7, -3)).toEqual(['f', 'g', 'h']);
+ expect(limitTo(str, 6, 3)).toEqual("wxyz");
+ expect(limitTo(str, 6, -3)).toEqual("xyz");
+ });
+
+ it('should return the entire string until index Y if X is negative and X+Y exceeds input length', function() {
+ expect(limitTo(items, -7, 3)).toEqual(['a', 'b', 'c']);
+ expect(limitTo(items, -7, -3)).toEqual(['a', 'b', 'c', 'd', 'e']);
+ expect(limitTo(str, -6, 3)).toEqual("tuv");
+ expect(limitTo(str, -6, -3)).toEqual("tuvw");
+ });
});

0 comments on commit aaae3cc

Please sign in to comment.