Skip to content

Commit

Permalink
feat(all): add iterator support to Array.from
Browse files Browse the repository at this point in the history
  • Loading branch information
AdamWillden authored and Adam Willden committed Mar 11, 2016
1 parent 80e5307 commit 5f23788
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 62 deletions.
92 changes: 30 additions & 62 deletions src/array.js
@@ -1,76 +1,44 @@
if (!Array.from) {
Array.from = (function () {
var toStr = Object.prototype.toString;
var isCallable = function (fn) {
return typeof fn === 'function' || toStr.call(fn) === '[object Function]';
var toInteger = function(it) {
return isNaN(it = +it) ? 0 : (it > 0 ? Math.floor : Math.ceil)(it);
};
var toInteger = function (value) {
var number = Number(value);
if (isNaN(number)) { return 0; }
if (number === 0 || !isFinite(number)) { return number; }
return (number > 0 ? 1 : -1) * Math.floor(Math.abs(number));
var toLength = function(it) {
return it > 0 ? min(toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991
};
var maxSafeInteger = Math.pow(2, 53) - 1;
var toLength = function (value) {
var len = toInteger(value);
return Math.min(Math.max(len, 0), maxSafeInteger);
var iterCall = function(iter, fn, a1, a2) {
try {
fn(a1, a2);
}
catch (E) {
if (typeof iter.return == 'function') iter.return();
throw E;
}
};

// The length property of the from method is 1.
return function from(arrayLike/*, mapFn, thisArg */) {
// 1. Let C be the this value.
var C = this;

// 2. Let items be ToObject(arrayLike).
var items = Object(arrayLike);

// 3. ReturnIfAbrupt(items).
if (arrayLike == null) {
throw new TypeError("Array.from requires an array-like object - not null or undefined");
}

// 4. If mapfn is undefined, then let mapping be false.
var mapFn = arguments.length > 1 ? arguments[1] : void undefined;
var T;
if (typeof mapFn !== 'undefined') {
// 5. else
// 5. a If IsCallable(mapfn) is false, throw a TypeError exception.
if (!isCallable(mapFn)) {
throw new TypeError('Array.from: when provided, the second argument must be a function');
}

// 5. b. If thisArg was supplied, let T be thisArg; else let T be undefined.
if (arguments.length > 2) {
T = arguments[2];
var O = Object(arrayLike)
, C = typeof this == 'function' ? this : Array
, aLen = arguments.length
, mapfn = aLen > 1 ? arguments[1] : undefined
, mapping = mapfn !== undefined
, index = 0
, iterFn = O[Symbol.iterator]
, length, result, step, iterator;
if (mapping) mapfn = mapfn.bind(aLen > 2 ? arguments[2] : undefined);
if (iterFn != undefined && !Array.isArray(arrayLike)) {
for (iterator = iterFn.call(O), result = new C; !(step = iterator.next()).done; index++) {
result[index] = mapping ? iterCall(mapfn, step.value, index) : step.value;
}
}

// 10. Let lenValue be Get(items, "length").
// 11. Let len be ToLength(lenValue).
var len = toLength(items.length);

// 13. If IsConstructor(C) is true, then
// 13. a. Let A be the result of calling the [[Construct]] internal method of C with an argument list containing the single item len.
// 14. a. Else, Let A be ArrayCreate(len).
var A = isCallable(C) ? Object(new C(len)) : new Array(len);

// 16. Let k be 0.
var k = 0;
// 17. Repeat, while k < len… (also steps a - h)
var kValue;
while (k < len) {
kValue = items[k];
if (mapFn) {
A[k] = typeof T === 'undefined' ? mapFn(kValue, k) : mapFn.call(T, kValue, k);
} else {
A[k] = kValue;
} else {
length = toLength(O.length);
for (result = new C(length); length > index; index++) {
result[index] = mapping ? mapfn(O[index], index) : O[index];
}
k += 1;
}
// 18. Let putStatus be Put(A, "length", len, true).
A.length = len;
// 20. Return A.
return A;
result.length = index;
return result;
};
}());
}
Expand Down
3 changes: 3 additions & 0 deletions src/collections.js
Expand Up @@ -202,6 +202,9 @@ import {PLATFORM} from 'aurelia-pal';
var p = [0], done = false;
itp.push(p);
return {
[Symbol.iterator]: function () {
return this;
},
next: function() {
var v, k = p[0];
if (!done && k < array.length) {
Expand Down

0 comments on commit 5f23788

Please sign in to comment.