Skip to content

Commit

Permalink
Fix Array#find and Array#findIndex on sparse arrays.
Browse files Browse the repository at this point in the history
The Array#find and Array#findIndex methods should skip elements which are
not present in the array-like object, but not terminate the search.
  • Loading branch information
cscott committed Feb 14, 2014
1 parent 947f5c5 commit 3ca6565
Show file tree
Hide file tree
Showing 2 changed files with 69 additions and 5 deletions.
14 changes: 9 additions & 5 deletions es6-shim.js
Original file line number Diff line number Diff line change
Expand Up @@ -610,9 +610,11 @@
throw new TypeError('Array#find: predicate must be a function');
}
var thisArg = arguments[1];
for (var i = 0, value; i < length && i in list; i++) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) return value;
for (var i = 0, value; i < length; i++) {
if (i in list) {
value = list[i];
if (predicate.call(thisArg, value, i, list)) return value;
}
}
return undefined;
},
Expand All @@ -624,8 +626,10 @@
throw new TypeError('Array#findIndex: predicate must be a function');
}
var thisArg = arguments[1];
for (var i = 0; i < length && i in list; i++) {
if (predicate.call(thisArg, list[i], i, list)) return i;
for (var i = 0; i < length; i++) {
if (i in list) {
if (predicate.call(thisArg, list[i], i, list)) return i;
}
}
return -1;
},
Expand Down
60 changes: 60 additions & 0 deletions test/array.js
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,36 @@ var runArrayTests = function() {
var found = Array.prototype.find.call(obj, function(item) { return item === 2; });
expect(found).to.equal(2);
});

it('should work with an array-like object with negative length', function() {
var obj = { '0': 1, '1': 2, '2': 3, length: -3 };
var found = Array.prototype.find.call(obj, function(item) {
throw new Error('should not reach here');
});
expect(found).to.equal(undefined);
});

it('should work with a sparse array', function() {
var obj = [1,,undefined];
var seen = [];
var found = Array.prototype.find.call(obj, function(item, idx) {
seen.push([idx, item]);
return false;
});
expect(found).to.equal(undefined);
expect(seen).to.eql([[0,1],[2,undefined]]);
});

it('should work with a sparse array-like object', function() {
var obj = { '0': 1, '2': undefined, length: 3.2 };
var seen = [];
var found = Array.prototype.find.call(obj, function(item, idx) {
seen.push([idx, item]);
return false;
});
expect(found).to.equal(undefined);
expect(seen).to.eql([[0,1],[2,undefined]]);
});
});

describe('Array#findIndex', function() {
Expand Down Expand Up @@ -197,6 +227,36 @@ var runArrayTests = function() {
var foundIndex = Array.prototype.findIndex.call(obj, function(item) { return item === 2; });
expect(foundIndex).to.equal(1);
});

it('should work with an array-like object with negative length', function() {
var obj = { '0': 1, '1': 2, '2': 3, length: -3 };
var foundIndex = Array.prototype.findIndex.call(obj, function(item) {
throw new Error('should not reach here');
});
expect(foundIndex).to.equal(-1);
});

it('should work with a sparse array', function() {
var obj = [1,,undefined];
var seen = [];
var foundIndex = Array.prototype.findIndex.call(obj, function(item, idx) {
seen.push([idx, item]);
return item === undefined;
});
expect(foundIndex).to.equal(2);
expect(seen).to.eql([[0,1],[2,undefined]]);
});

it('should work with a sparse array-like object', function() {
var obj = { '0': 1, '2': undefined, length: 3.2 };
var seen = [];
var foundIndex = Array.prototype.findIndex.call(obj, function(item, idx) {
seen.push([idx, item]);
return false;
});
expect(foundIndex).to.equal(-1);
expect(seen).to.eql([[0,1],[2,undefined]]);
});
});

describe('ArrayIterator', function() {
Expand Down

0 comments on commit 3ca6565

Please sign in to comment.