diff --git a/lodash.js b/lodash.js index 61bd160be..3797460cc 100644 --- a/lodash.js +++ b/lodash.js @@ -3511,6 +3511,34 @@ return result; } + /** + * The base implementation of `_.repeat` which doesn't coerce arguments. + * + * @private + * @param {string} string The string to repeat. + * @param {number} n The number of times to repeat the string. + * @returns {string} Returns the repeated string. + */ + function baseRepeat(string, n) { + var result = ''; + if (!string || n < 1 || n > MAX_SAFE_INTEGER) { + return result; + } + // Leverage the exponentiation by squaring algorithm for a faster repeat. + // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. + do { + if (n % 2) { + result += string; + } + n = nativeFloor(n / 2); + if (n) { + string += string; + } + } while (n); + + return result; + } + /** * The base implementation of `_.set`. * @@ -4560,14 +4588,18 @@ if (!length || strLength >= length) { return ''; } - var padLength = length - strLength; chars = chars === undefined ? ' ' : (chars + ''); chars = chars == '' ? ' ' : chars; + length -= strLength; - var result = repeat(chars, nativeCeil(padLength / stringSize(chars))); + var charsLength = chars.length; + if (charsLength == 1) { + return baseRepeat(chars, length); + } + var result = baseRepeat(chars, nativeCeil(length / stringSize(chars))); return reHasComplexSymbol.test(chars) - ? stringToArray(result).slice(0, padLength).join('') - : result.slice(0, padLength); + ? stringToArray(result).slice(0, length).join('') + : result.slice(0, length); } /** @@ -13170,26 +13202,7 @@ * // => '' */ function repeat(string, n) { - string = toString(string); - n = toInteger(n); - - var result = ''; - if (!string || n < 1 || n > MAX_SAFE_INTEGER) { - return result; - } - // Leverage the exponentiation by squaring algorithm for a faster repeat. - // See https://en.wikipedia.org/wiki/Exponentiation_by_squaring for more details. - do { - if (n % 2) { - result += string; - } - n = nativeFloor(n / 2); - if (n) { - string += string; - } - } while (n); - - return result; + return baseRepeat(toString(string), toInteger(n)); } /** @@ -14107,13 +14120,13 @@ /** * Creates a function that invokes `func` with the arguments of the created - * function. If `func` is a property name the created callback returns the - * property value for a given element. If `func` is an object the created - * callback returns `true` for elements that contain the equivalent object - * properties, otherwise it returns `false`. + * function. If `func` is a property name the created function returns the + * property value for a given element. If `func` is an array or object the + * created function returns `true` for elements that contain the equivalent + * source properties, otherwise it returns `false`. * * @static - * @since 0.1.0 + * @since 4.0.0 * @memberOf _ * @category Util * @param {*} [func=_.identity] The value to convert to a callback. @@ -14121,20 +14134,31 @@ * @example * * var users = [ - * { 'user': 'barney', 'age': 36 }, - * { 'user': 'fred', 'age': 40 } + * { 'user': 'barney', 'age': 36, 'active': true }, + * { 'user': 'fred', 'age': 40, 'active': false } * ]; * + * // The `_.matches` iteratee shorthand. + * _.filter(users, _.iteratee({ 'user': 'barney', 'active': true })); + * // => [{ 'user': 'barney', 'age': 36, 'active': true }] + * + * // The `_.matchesProperty` iteratee shorthand. + * _.filter(users, _.iteratee(['user', 'fred'])); + * // => [{ 'user': 'fred', 'age': 40 }] + * + * // The `_.property` iteratee shorthand. + * _.map(users, _.iteratee('user')); + * // => ['barney', 'fred'] + * * // Create custom iteratee shorthands. - * _.iteratee = _.wrap(_.iteratee, function(callback, func) { - * var p = /^(\S+)\s*([<>])\s*(\S+)$/.exec(func); - * return !p ? callback(func) : function(object) { - * return (p[2] == '>' ? object[p[1]] > p[3] : object[p[1]] < p[3]); + * _.iteratee = _.wrap(_.iteratee, function(iteratee, func) { + * return !_.isRegExp(func) ? iteratee(func) : function(string) { + * return func.test(string); * }; * }); * - * _.filter(users, 'age > 36'); - * // => [{ 'user': 'fred', 'age': 40 }] + * _.filter(['abc', 'def'], /ef/); + * // => ['def'] */ function iteratee(func) { return baseIteratee(typeof func == 'function' ? func : baseClone(func, true));