diff --git a/README.md b/README.md
index 04922e847..2d65901b4 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# lodash v3.0.1
+# lodash v3.1.0
The [modern build](https://github.com/lodash/lodash/wiki/Build-Differences) of [lodash](https://lodash.com/) exported as [AMD](https://github.com/amdjs/amdjs-api/wiki/AMD) modules.
diff --git a/chain/lodash.js b/chain/lodash.js
index c30b59c2c..603126a15 100644
--- a/chain/lodash.js
+++ b/chain/lodash.js
@@ -54,14 +54,14 @@ define(['../internal/LodashWrapper', '../internal/arrayCopy', '../lang/isArray',
* `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`,
* `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`,
* `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`,
- * `isFunction`, `isMatch` , `isNative`, `isNaN`, `isNull`, `isNumber`,
+ * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
* `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
* `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`,
* `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`,
* `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`,
* `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`,
- * `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
- * `unescape`, `uniqueId`, `value`, and `words`
+ * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`,
+ * `trunc`, `unescape`, `uniqueId`, `value`, and `words`
*
* The wrapper function `sample` will return a wrapped value when `n` is provided,
* otherwise an unwrapped value is returned.
diff --git a/collection/findWhere.js b/collection/findWhere.js
index c949868fd..bf7098a6d 100644
--- a/collection/findWhere.js
+++ b/collection/findWhere.js
@@ -1,4 +1,4 @@
-define(['./find', '../utility/matches'], function(find, matches) {
+define(['../internal/baseMatches', './find'], function(baseMatches, find) {
/**
* Performs a deep comparison between each element in `collection` and the
@@ -25,7 +25,7 @@ define(['./find', '../utility/matches'], function(find, matches) {
* // => 'fred'
*/
function findWhere(collection, source) {
- return find(collection, matches(source));
+ return find(collection, baseMatches(source));
}
return findWhere;
diff --git a/collection/pluck.js b/collection/pluck.js
index f3052bc26..7d8505a4c 100644
--- a/collection/pluck.js
+++ b/collection/pluck.js
@@ -1,4 +1,4 @@
-define(['./map', '../utility/property'], function(map, property) {
+define(['../internal/baseProperty', './map'], function(baseProperty, map) {
/**
* Gets the value of `key` from all elements in `collection`.
@@ -24,7 +24,7 @@ define(['./map', '../utility/property'], function(map, property) {
* // => [36, 40] (iteration order is not guaranteed)
*/
function pluck(collection, key) {
- return map(collection, property(key));
+ return map(collection, baseProperty(key + ''));
}
return pluck;
diff --git a/collection/where.js b/collection/where.js
index 433abb8f6..d7d6613cb 100644
--- a/collection/where.js
+++ b/collection/where.js
@@ -1,4 +1,4 @@
-define(['./filter', '../utility/matches'], function(filter, matches) {
+define(['../internal/baseMatches', './filter'], function(baseMatches, filter) {
/**
* Performs a deep comparison between each element in `collection` and the
@@ -28,7 +28,7 @@ define(['./filter', '../utility/matches'], function(filter, matches) {
* // => ['barney', 'fred']
*/
function where(collection, source) {
- return filter(collection, matches(source));
+ return filter(collection, baseMatches(source));
}
return where;
diff --git a/internal/baseCallback.js b/internal/baseCallback.js
index de8dace0c..9f1a1a9a6 100644
--- a/internal/baseCallback.js
+++ b/internal/baseCallback.js
@@ -22,7 +22,7 @@ define(['./baseMatches', './baseProperty', './bindCallback', '../utility/identit
}
// Handle "_.property" and "_.matches" style callback shorthands.
return type == 'object'
- ? baseMatches(func, !argCount)
+ ? baseMatches(func)
: baseProperty(func + '');
}
diff --git a/internal/baseMatches.js b/internal/baseMatches.js
index 2b8fac751..f980830ac 100644
--- a/internal/baseMatches.js
+++ b/internal/baseMatches.js
@@ -1,4 +1,4 @@
-define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys'], function(baseClone, baseIsMatch, isStrictComparable, keys) {
+define(['./baseIsMatch', './isStrictComparable', '../object/keys'], function(baseIsMatch, isStrictComparable, keys) {
/** Used for native method references. */
var objectProto = Object.prototype;
@@ -12,10 +12,9 @@ define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys'
*
* @private
* @param {Object} source The object of property values to match.
- * @param {boolean} [isCloned] Specify cloning the source object.
* @returns {Function} Returns the new function.
*/
- function baseMatches(source, isCloned) {
+ function baseMatches(source) {
var props = keys(source),
length = props.length;
@@ -29,9 +28,6 @@ define(['./baseClone', './baseIsMatch', './isStrictComparable', '../object/keys'
};
}
}
- if (isCloned) {
- source = baseClone(source, true);
- }
var values = Array(length),
strictCompareFlags = Array(length);
diff --git a/internal/isIndex.js b/internal/isIndex.js
index 8566b1ba3..28f79eef4 100644
--- a/internal/isIndex.js
+++ b/internal/isIndex.js
@@ -2,7 +2,7 @@ define([], function() {
/**
* Used as the maximum length of an array-like value.
- * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
* for more details.
*/
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
diff --git a/internal/isIterateeCall.js b/internal/isIterateeCall.js
index 7174a8dd6..99e93d5bf 100644
--- a/internal/isIterateeCall.js
+++ b/internal/isIterateeCall.js
@@ -18,7 +18,7 @@ define(['./isIndex', './isLength', '../lang/isObject'], function(isIndex, isLeng
var length = object.length,
prereq = isLength(length) && isIndex(index, length);
} else {
- prereq = type == 'string' && index in value;
+ prereq = type == 'string' && index in object;
}
return prereq && object[index] === value;
}
diff --git a/internal/isLength.js b/internal/isLength.js
index 3069b5435..165e7a0b7 100644
--- a/internal/isLength.js
+++ b/internal/isLength.js
@@ -2,7 +2,7 @@ define([], function() {
/**
* Used as the maximum length of an array-like value.
- * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
* for more details.
*/
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
@@ -10,6 +10,10 @@ define([], function() {
/**
* Checks if `value` is a valid array-like length.
*
+ * **Note:** This function is based on ES `ToLength`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * for more details.
+ *
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
diff --git a/main.js b/main.js
index fa8a8d40a..09056091a 100644
--- a/main.js
+++ b/main.js
@@ -1,6 +1,6 @@
/**
* @license
- * lodash 3.0.1 (Custom Build)
+ * lodash 3.1.0 (Custom Build)
* Build: `lodash modern exports="amd" -d -o ./main.js`
* Copyright 2012-2015 The Dojo Foundation
* Based on Underscore.js 1.7.0
@@ -13,7 +13,7 @@
var undefined;
/** Used as the semantic version number. */
- var VERSION = '3.0.1';
+ var VERSION = '3.1.0';
/** Used to compose bitmasks for wrapper metadata. */
var BIND_FLAG = 1,
@@ -766,7 +766,7 @@
/**
* Used as the maximum length of an array-like value.
- * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * See the [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-number.max_safe_integer)
* for more details.
*/
var MAX_SAFE_INTEGER = Math.pow(2, 53) - 1;
@@ -824,14 +824,14 @@
* `findLast`, `findLastIndex`, `findLastKey`, `findWhere`, `first`, `has`,
* `identity`, `includes`, `indexOf`, `isArguments`, `isArray`, `isBoolean`,
* `isDate`, `isElement`, `isEmpty`, `isEqual`, `isError`, `isFinite`,
- * `isFunction`, `isMatch` , `isNative`, `isNaN`, `isNull`, `isNumber`,
+ * `isFunction`, `isMatch`, `isNative`, `isNaN`, `isNull`, `isNumber`,
* `isObject`, `isPlainObject`, `isRegExp`, `isString`, `isUndefined`,
* `isTypedArray`, `join`, `kebabCase`, `last`, `lastIndexOf`, `max`, `min`,
* `noConflict`, `now`, `pad`, `padLeft`, `padRight`, `parseInt`, `pop`,
* `random`, `reduce`, `reduceRight`, `repeat`, `result`, `runInContext`,
* `shift`, `size`, `snakeCase`, `some`, `sortedIndex`, `sortedLastIndex`,
- * `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`, `trunc`,
- * `unescape`, `uniqueId`, `value`, and `words`
+ * `startCase`, `startsWith`, `template`, `trim`, `trimLeft`, `trimRight`,
+ * `trunc`, `unescape`, `uniqueId`, `value`, and `words`
*
* The wrapper function `sample` will return a wrapped value when `n` is provided,
* otherwise an unwrapped value is returned.
@@ -1644,7 +1644,7 @@
}
// Handle "_.property" and "_.matches" style callback shorthands.
return type == 'object'
- ? baseMatches(func, !argCount)
+ ? baseMatches(func)
: baseProperty(func + '');
}
@@ -2265,10 +2265,9 @@
*
* @private
* @param {Object} source The object of property values to match.
- * @param {boolean} [isCloned] Specify cloning the source object.
* @returns {Function} Returns the new function.
*/
- function baseMatches(source, isCloned) {
+ function baseMatches(source) {
var props = keys(source),
length = props.length;
@@ -2282,9 +2281,6 @@
};
}
}
- if (isCloned) {
- source = baseClone(source, true);
- }
var values = Array(length),
strictCompareFlags = Array(length);
@@ -3595,7 +3591,7 @@
var length = object.length,
prereq = isLength(length) && isIndex(index, length);
} else {
- prereq = type == 'string' && index in value;
+ prereq = type == 'string' && index in object;
}
return prereq && object[index] === value;
}
@@ -3603,6 +3599,10 @@
/**
* Checks if `value` is a valid array-like length.
*
+ * **Note:** This function is based on ES `ToLength`. See the
+ * [ES spec](https://people.mozilla.org/~jorendorff/es6-draft.html#sec-tolength)
+ * for more details.
+ *
* @private
* @param {*} value The value to check.
* @returns {boolean} Returns `true` if `value` is a valid length, else `false`.
@@ -5673,7 +5673,7 @@
* // => 'fred'
*/
function findWhere(collection, source) {
- return find(collection, matches(source));
+ return find(collection, baseMatches(source));
}
/**
@@ -6050,7 +6050,7 @@
* // => [36, 40] (iteration order is not guaranteed)
*/
function pluck(collection, key) {
- return map(collection, property(key));
+ return map(collection, baseProperty(key + ''));
}
/**
@@ -6421,7 +6421,7 @@
* // => ['barney', 'fred']
*/
function where(collection, source) {
- return filter(collection, matches(source));
+ return filter(collection, baseMatches(source));
}
/*------------------------------------------------------------------------*/
@@ -9066,7 +9066,7 @@
*/
var camelCase = createCompounder(function(result, word, index) {
word = word.toLowerCase();
- return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word;
+ return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
});
/**
@@ -9417,16 +9417,41 @@
* _.snakeCase('Foo Bar');
* // => 'foo_bar'
*
- * _.snakeCase('--foo-bar');
+ * _.snakeCase('fooBar');
* // => 'foo_bar'
*
- * _.snakeCase('fooBar');
+ * _.snakeCase('--foo-bar');
* // => 'foo_bar'
*/
var snakeCase = createCompounder(function(result, word, index) {
return result + (index ? '_' : '') + word.toLowerCase();
});
+ /**
+ * Converts `string` to start case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the start cased string.
+ * @example
+ *
+ * _.startCase('--foo-bar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('fooBar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('__foo_bar__');
+ * // => 'Foo Bar'
+ */
+ var startCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
+ });
+
/**
* Checks if `string` starts with the given target string.
*
@@ -9686,7 +9711,7 @@
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
}
- chars = baseToString(chars);
+ chars = (chars + '');
return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
}
@@ -9717,7 +9742,7 @@
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string))
}
- return string.slice(charsLeftIndex(string, baseToString(chars)));
+ return string.slice(charsLeftIndex(string, (chars + '')));
}
/**
@@ -9747,7 +9772,7 @@
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(0, trimmedRightIndex(string) + 1)
}
- return string.slice(0, charsRightIndex(string, baseToString(chars)) + 1);
+ return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
}
/**
@@ -9954,7 +9979,9 @@
if (guard && isIterateeCall(func, thisArg, guard)) {
thisArg = null;
}
- return baseCallback(func, thisArg);
+ return isObjectLike(func)
+ ? matches(func)
+ : baseCallback(func, thisArg);
}
/**
@@ -10022,7 +10049,7 @@
* // => { 'user': 'barney', 'age': 36 }
*/
function matches(source) {
- return baseMatches(source, true);
+ return baseMatches(baseClone(source, true));
}
/**
@@ -10519,6 +10546,7 @@
lodash.some = some;
lodash.sortedIndex = sortedIndex;
lodash.sortedLastIndex = sortedLastIndex;
+ lodash.startCase = startCase;
lodash.startsWith = startsWith;
lodash.template = template;
lodash.trim = trim;
@@ -10644,10 +10672,10 @@
// Add `LazyWrapper` methods for `_.pluck` and `_.where`.
arrayEach(['pluck', 'where'], function(methodName, index) {
var operationName = index ? 'filter' : 'map',
- createCallback = index ? matches : property;
+ createCallback = index ? baseMatches : baseProperty;
LazyWrapper.prototype[methodName] = function(value) {
- return this[operationName](createCallback(value));
+ return this[operationName](createCallback(index ? value : (value + '')));
};
});
diff --git a/package.json b/package.json
index 5d26c56b0..5fcad7450 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "lodash",
- "version": "3.0.1",
+ "version": "3.1.0",
"main": "main.js",
"private": true,
"volo": {
diff --git a/string.js b/string.js
index 87406d0d5..b1e317936 100644
--- a/string.js
+++ b/string.js
@@ -1,4 +1,4 @@
-define(['./string/camelCase', './string/capitalize', './string/deburr', './string/endsWith', './string/escape', './string/escapeRegExp', './string/kebabCase', './string/pad', './string/padLeft', './string/padRight', './string/parseInt', './string/repeat', './string/snakeCase', './string/startsWith', './string/template', './string/templateSettings', './string/trim', './string/trimLeft', './string/trimRight', './string/trunc', './string/unescape', './string/words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, pad, padLeft, padRight, parseInt, repeat, snakeCase, startsWith, template, templateSettings, trim, trimLeft, trimRight, trunc, unescape, words) {
+define(['./string/camelCase', './string/capitalize', './string/deburr', './string/endsWith', './string/escape', './string/escapeRegExp', './string/kebabCase', './string/pad', './string/padLeft', './string/padRight', './string/parseInt', './string/repeat', './string/snakeCase', './string/startCase', './string/startsWith', './string/template', './string/templateSettings', './string/trim', './string/trimLeft', './string/trimRight', './string/trunc', './string/unescape', './string/words'], function(camelCase, capitalize, deburr, endsWith, escape, escapeRegExp, kebabCase, pad, padLeft, padRight, parseInt, repeat, snakeCase, startCase, startsWith, template, templateSettings, trim, trimLeft, trimRight, trunc, unescape, words) {
return {
'camelCase': camelCase,
'capitalize': capitalize,
@@ -13,6 +13,7 @@ define(['./string/camelCase', './string/capitalize', './string/deburr', './strin
'parseInt': parseInt,
'repeat': repeat,
'snakeCase': snakeCase,
+ 'startCase': startCase,
'startsWith': startsWith,
'template': template,
'templateSettings': templateSettings,
diff --git a/string/camelCase.js b/string/camelCase.js
index 63e41b387..88f374b53 100644
--- a/string/camelCase.js
+++ b/string/camelCase.js
@@ -22,7 +22,7 @@ define(['../internal/createCompounder'], function(createCompounder) {
*/
var camelCase = createCompounder(function(result, word, index) {
word = word.toLowerCase();
- return index ? (result + word.charAt(0).toUpperCase() + word.slice(1)) : word;
+ return result + (index ? (word.charAt(0).toUpperCase() + word.slice(1)) : word);
});
return camelCase;
diff --git a/string/snakeCase.js b/string/snakeCase.js
index 3f338b296..607f6b852 100644
--- a/string/snakeCase.js
+++ b/string/snakeCase.js
@@ -14,10 +14,10 @@ define(['../internal/createCompounder'], function(createCompounder) {
* _.snakeCase('Foo Bar');
* // => 'foo_bar'
*
- * _.snakeCase('--foo-bar');
+ * _.snakeCase('fooBar');
* // => 'foo_bar'
*
- * _.snakeCase('fooBar');
+ * _.snakeCase('--foo-bar');
* // => 'foo_bar'
*/
var snakeCase = createCompounder(function(result, word, index) {
diff --git a/string/startCase.js b/string/startCase.js
new file mode 100644
index 000000000..6a0d4b156
--- /dev/null
+++ b/string/startCase.js
@@ -0,0 +1,29 @@
+define(['../internal/createCompounder'], function(createCompounder) {
+
+ /**
+ * Converts `string` to start case.
+ * See [Wikipedia](https://en.wikipedia.org/wiki/Letter_case#Stylistic_or_specialised_usage)
+ * for more details.
+ *
+ * @static
+ * @memberOf _
+ * @category String
+ * @param {string} [string=''] The string to convert.
+ * @returns {string} Returns the start cased string.
+ * @example
+ *
+ * _.startCase('--foo-bar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('fooBar');
+ * // => 'Foo Bar'
+ *
+ * _.startCase('__foo_bar__');
+ * // => 'Foo Bar'
+ */
+ var startCase = createCompounder(function(result, word, index) {
+ return result + (index ? ' ' : '') + (word.charAt(0).toUpperCase() + word.slice(1));
+ });
+
+ return startCase;
+});
diff --git a/string/trim.js b/string/trim.js
index 68aa6c84f..ea2b6f6ee 100644
--- a/string/trim.js
+++ b/string/trim.js
@@ -30,7 +30,7 @@ define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/c
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string), trimmedRightIndex(string) + 1);
}
- chars = baseToString(chars);
+ chars = (chars + '');
return string.slice(charsLeftIndex(string, chars), charsRightIndex(string, chars) + 1);
}
diff --git a/string/trimLeft.js b/string/trimLeft.js
index 310e75ff6..b11eff02d 100644
--- a/string/trimLeft.js
+++ b/string/trimLeft.js
@@ -27,7 +27,7 @@ define(['../internal/baseToString', '../internal/charsLeftIndex', '../internal/i
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(trimmedLeftIndex(string))
}
- return string.slice(charsLeftIndex(string, baseToString(chars)));
+ return string.slice(charsLeftIndex(string, (chars + '')));
}
return trimLeft;
diff --git a/string/trimRight.js b/string/trimRight.js
index 2ed4123e3..f9627443d 100644
--- a/string/trimRight.js
+++ b/string/trimRight.js
@@ -27,7 +27,7 @@ define(['../internal/baseToString', '../internal/charsRightIndex', '../internal/
if (guard ? isIterateeCall(value, chars, guard) : chars == null) {
return string.slice(0, trimmedRightIndex(string) + 1)
}
- return string.slice(0, charsRightIndex(string, baseToString(chars)) + 1);
+ return string.slice(0, charsRightIndex(string, (chars + '')) + 1);
}
return trimRight;
diff --git a/utility/callback.js b/utility/callback.js
index bed0d9a60..4523e9f37 100644
--- a/utility/callback.js
+++ b/utility/callback.js
@@ -1,4 +1,4 @@
-define(['../internal/baseCallback', '../internal/isIterateeCall'], function(baseCallback, isIterateeCall) {
+define(['../internal/baseCallback', '../internal/isIterateeCall', '../internal/isObjectLike', './matches'], function(baseCallback, isIterateeCall, isObjectLike, matches) {
/**
* Creates a function bound to an optional `thisArg`. If `func` is a property
@@ -39,7 +39,9 @@ define(['../internal/baseCallback', '../internal/isIterateeCall'], function(base
if (guard && isIterateeCall(func, thisArg, guard)) {
thisArg = null;
}
- return baseCallback(func, thisArg);
+ return isObjectLike(func)
+ ? matches(func)
+ : baseCallback(func, thisArg);
}
return callback;
diff --git a/utility/matches.js b/utility/matches.js
index 554274588..4a73a2a3b 100644
--- a/utility/matches.js
+++ b/utility/matches.js
@@ -1,4 +1,4 @@
-define(['../internal/baseMatches'], function(baseMatches) {
+define(['../internal/baseClone', '../internal/baseMatches'], function(baseClone, baseMatches) {
/**
* Creates a function which performs a deep comparison between a given object
@@ -26,7 +26,7 @@ define(['../internal/baseMatches'], function(baseMatches) {
* // => { 'user': 'barney', 'age': 36 }
*/
function matches(source) {
- return baseMatches(source, true);
+ return baseMatches(baseClone(source, true));
}
return matches;