From 5388d8a7b0823fdccd7b52b313898a3d4142db78 Mon Sep 17 00:00:00 2001 From: John-David Dalton Date: Sat, 13 Feb 2016 12:55:47 -0800 Subject: [PATCH] Rename `_.asArray` to `_.castArray` and add `_.castFunction` and `_.castPath`. --- lodash.js | 188 +++++++++++++++++++++++++++------------------------ test/test.js | 72 ++++++++------------ 2 files changed, 131 insertions(+), 129 deletions(-) diff --git a/lodash.js b/lodash.js index d5aa8903e..df22afca8 100644 --- a/lodash.js +++ b/lodash.js @@ -2203,6 +2203,17 @@ return result; } + /** + * Casts `value` to an empty array if it's not an array like object. + * + * @private + * @param {*} value The value to inspect. + * @returns {Array} Returns the array-like object. + */ + function baseCastArrayLikeObject(value) { + return isArrayLikeObject(value) ? value : []; + } + /** * The base implementation of `_.clamp` which doesn't coerce arguments to numbers. * @@ -2613,7 +2624,7 @@ * @returns {*} Returns the resolved value. */ function baseGet(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); var index = 0, length = path.length; @@ -2749,7 +2760,7 @@ */ function baseInvoke(object, path, args) { if (!isKey(path, object)) { - path = baseToPath(path); + path = castPath(path); object = parent(object, path); path = last(path); } @@ -3272,7 +3283,7 @@ splice.call(array, index, 1); } else if (!isKey(index, array)) { - var path = baseToPath(index), + var path = castPath(index), object = parent(array, path); if (object != null) { @@ -3334,7 +3345,7 @@ * @returns {Object} Returns `object`. */ function baseSet(object, path, value, customizer) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); var index = -1, length = path.length, @@ -3540,18 +3551,6 @@ return result; } - /** - * The base implementation of `_.toPath` which only converts `value` to a - * path if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the property path array. - */ - function baseToPath(value) { - return isArray(value) ? value : stringToPath(value); - } - /** * The base implementation of `_.uniqBy` without support for iteratee shorthands. * @@ -3621,7 +3620,7 @@ * @returns {boolean} Returns `true` if the property is deleted, else `false`. */ function baseUnset(object, path) { - path = isKey(path, object) ? [path + ''] : baseToPath(path); + path = isKey(path, object) ? [path + ''] : castPath(path); object = parent(object, path); var key = last(path); return (object != null && has(object, key)) ? delete object[key] : true; @@ -4944,7 +4943,7 @@ } var result = hasFunc(object, path); if (!result && !isKey(path)) { - path = baseToPath(path); + path = castPath(path); object = parent(object, path); if (object != null) { path = last(path); @@ -5325,28 +5324,6 @@ return result; } - /** - * Converts `value` to an array-like object if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Array} Returns the array-like object. - */ - function toArrayLikeObject(value) { - return isArrayLikeObject(value) ? value : []; - } - - /** - * Converts `value` to a function if it's not one. - * - * @private - * @param {*} value The value to process. - * @returns {Function} Returns the function. - */ - function toFunction(value) { - return typeof value == 'function' ? value : identity; - } - /** * Creates a clone of `wrapper`. * @@ -5986,7 +5963,7 @@ * // => [2] */ var intersection = rest(function(arrays) { - var mapped = arrayMap(arrays, toArrayLikeObject); + var mapped = arrayMap(arrays, baseCastArrayLikeObject); return (mapped.length && mapped[0] === arrays[0]) ? baseIntersection(mapped) : []; @@ -6014,7 +5991,7 @@ */ var intersectionBy = rest(function(arrays) { var iteratee = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (iteratee === last(mapped)) { iteratee = undefined; @@ -6047,7 +6024,7 @@ */ var intersectionWith = rest(function(arrays) { var comparator = last(arrays), - mapped = arrayMap(arrays, toArrayLikeObject); + mapped = arrayMap(arrays, baseCastArrayLikeObject); if (comparator === last(mapped)) { comparator = undefined; @@ -7662,7 +7639,7 @@ function forEach(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEach(collection, iteratee) - : baseEach(collection, toFunction(iteratee)); + : baseEach(collection, castFunction(iteratee)); } /** @@ -7686,7 +7663,7 @@ function forEachRight(collection, iteratee) { return (typeof iteratee == 'function' && isArray(collection)) ? arrayEachRight(collection, iteratee) - : baseEachRight(collection, toFunction(iteratee)); + : baseEachRight(collection, castFunction(iteratee)); } /** @@ -9243,6 +9220,76 @@ /*------------------------------------------------------------------------*/ + /** + * Casts `value` as an array if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast array. + * @example + * + * _.castArray(1); + * // => [1] + * + * _.castArray({ 'a': 1 }); + * // => [{ 'a': 1 }] + * + * _.castArray('abc'); + * // => ['abc'] + * + * _.castArray(null); + * // => [null] + * + * _.castArray(undefined); + * // => [undefined] + * + * _.castArray(); + * // => [] + * + * var array = [1, 2, 3]; + * console.log(_.castArray(array) === array); + * // => true + */ + function castArray() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : [value]; + } + + /** + * Casts `value` to a function if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Function} Returns the cast function. + */ + function castFunction(value) { + return isFunction(value) ? value : identity; + } + + /** + * Casts `value` to a path if it's not one. + * + * @static + * @memberOf _ + * @category Lang + * @param {*} value The value to inspect. + * @returns {Array} Returns the cast property path array. + */ + function castPath() { + if (!arguments.length) { + return []; + } + var value = arguments[0]; + return isArray(value) ? value : stringToPath(value); + } + /** * Creates a shallow clone of `value`. * @@ -10432,41 +10479,6 @@ return value <= other; } - /** - * Converts a `value` to an array. - * - * @static - * @memberOf _ - * @category Lang - * @param {*} value The value to convert. - * @returns {Array} Returns the converted array. - * @example - * - * _.toArray({ 'a': 1, 'b': 2 }); - * // => [{ 'a': 1, 'b': 2 }] - * - * _.toArray([1, 2, 3]); - * // => [1, 2, 3] - * - * _.toArray('abc'); - * // => ['abc'] - * - * _.toArray(1); - * // => [1] - * - * _.toArray(null); - * // => [null] - */ - function asArray(value) { - if (isArray(value)) { - return copyArray(value); - } - if (iteratorSymbol && value && value[iteratorSymbol] && !isString(value)) { - return iteratorToArray(value[iteratorSymbol]()); - } - return [value]; - } - /** * Converts `value` to an array. * @@ -11036,7 +11048,7 @@ * // => logs 'a', 'b', then 'c' (iteration order is not guaranteed) */ function forIn(object, iteratee) { - return object == null ? object : baseFor(object, toFunction(iteratee), keysIn); + return object == null ? object : baseFor(object, castFunction(iteratee), keysIn); } /** @@ -11064,7 +11076,7 @@ * // => logs 'c', 'b', then 'a' assuming `_.forIn` logs 'a', 'b', then 'c' */ function forInRight(object, iteratee) { - return object == null ? object : baseForRight(object, toFunction(iteratee), keysIn); + return object == null ? object : baseForRight(object, castFunction(iteratee), keysIn); } /** @@ -11094,7 +11106,7 @@ * // => logs 'a' then 'b' (iteration order is not guaranteed) */ function forOwn(object, iteratee) { - return object && baseForOwn(object, toFunction(iteratee)); + return object && baseForOwn(object, castFunction(iteratee)); } /** @@ -11122,7 +11134,7 @@ * // => logs 'b' then 'a' assuming `_.forOwn` logs 'a' then 'b' */ function forOwnRight(object, iteratee) { - return object && baseForOwnRight(object, toFunction(iteratee)); + return object && baseForOwnRight(object, castFunction(iteratee)); } /** @@ -11685,7 +11697,7 @@ */ function result(object, path, defaultValue) { if (!isKey(path, object)) { - path = baseToPath(path); + path = castPath(path); var result = get(object, path); object = parent(object, path); } else { @@ -13854,7 +13866,7 @@ var index = MAX_ARRAY_LENGTH, length = nativeMin(n, MAX_ARRAY_LENGTH); - iteratee = toFunction(iteratee); + iteratee = castFunction(iteratee); n -= MAX_ARRAY_LENGTH; var result = baseTimes(length, iteratee); @@ -14241,7 +14253,6 @@ // Add functions that return wrapped values when chaining. lodash.after = after; lodash.ary = ary; - lodash.asArray = asArray; lodash.assign = assign; lodash.assignIn = assignIn; lodash.assignInWith = assignInWith; @@ -14251,6 +14262,9 @@ lodash.bind = bind; lodash.bindAll = bindAll; lodash.bindKey = bindKey; + lodash.castArray = castArray; + lodash.castFunction = castFunction; + lodash.castPath = castPath; lodash.chain = chain; lodash.chunk = chunk; lodash.compact = compact; diff --git a/test/test.js b/test/test.js index 8c49c0a50..28d1e29f8 100644 --- a/test/test.js +++ b/test/test.js @@ -2158,6 +2158,35 @@ /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.castArray'); + + (function() { + QUnit.test('should wrap non array items in an array', function(assert) { + assert.expect(1); + + var values = falsey.concat(true, 1, 'a', { 'a': 1 }), + expected = lodashStable.map(values, function(value) { return [value]; }), + actual = lodashStable.map(values, _.castArray); + + assert.deepEqual(actual, expected); + }); + + QUnit.test('should return array values by reference', function(assert) { + assert.expect(1); + + var array = [1]; + assert.strictEqual(_.castArray(array), array); + }); + + QUnit.test('should return an empty array when no arguments are given', function(assert) { + assert.expect(1); + + assert.deepEqual(_.castArray(), []); + }); + }()); + + /*--------------------------------------------------------------------------*/ + QUnit.module('lodash.chain'); (function() { @@ -21185,47 +21214,6 @@ /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.asArray'); - - (function() { - var wrapCases = [null, void 0, 1, '', 'ab', 0, {a: 1}, Object('xyz')]; - - QUnit.test('should wrap non array items in an array', function(assert) { - assert.expect(wrapCases.length * 2); - - _.each(wrapCases, function(val) { - var result = _.asArray(val); - assert.deepEqual(result, [val], 'for value ' + val); - assert.strictEqual(result[0], val, 'should not copy the value'); - }); - }); - - QUnit.test('should an array copy if provided array', function(assert) { - assert.expect(2); - - var arr = [1, 2, '3']; - assert.deepEqual(_.asArray(arr), arr); - assert.notStrictEqual(_.asArray(arr), arr); - }); - - QUnit.test('should convert iterables to arrays', function(assert) { - assert.expect(1); - - if (!isNpm && Symbol && Symbol.iterator) { - var object = { '0': 'a', 'length': 1 }; - object[Symbol.iterator] = arrayProto[Symbol.iterator]; - - assert.deepEqual(_.asArray(object), ['a']); - } - else { - skipAssert(assert); - } - }); - - }()); - - /*--------------------------------------------------------------------------*/ - QUnit.module('lodash.toLower'); (function() { @@ -24125,7 +24113,7 @@ var acceptFalsey = lodashStable.difference(allMethods, rejectFalsey); QUnit.test('should accept falsey arguments', function(assert) { - assert.expect(297); + assert.expect(299); var emptyArrays = lodashStable.map(falsey, alwaysEmptyArray);