830 * |
1742 * |
831 * @private |
1743 * @private |
832 * @param {Object} prototype The object to inherit from. |
1744 * @param {Object} prototype The object to inherit from. |
833 * @returns {Object} Returns the new object. |
1745 * @returns {Object} Returns the new object. |
834 */ |
1746 */ |
835 function baseCreate(prototype, properties) { |
1747 var baseCreate = (function() { |
836 return isObject(prototype) ? nativeCreate(prototype) : {}; |
1748 function object() {} |
837 } |
1749 return function(prototype) { |
838 // fallback for browsers without `Object.create` |
1750 if (isObject(prototype)) { |
839 if (!nativeCreate) { |
1751 object.prototype = prototype; |
840 baseCreate = (function() { |
1752 var result = new object; |
841 function Object() {} |
1753 object.prototype = undefined; |
842 return function(prototype) { |
1754 } |
843 if (isObject(prototype)) { |
1755 return result || {}; |
844 Object.prototype = prototype; |
1756 }; |
845 var result = new Object; |
1757 }()); |
846 Object.prototype = null; |
1758 |
|
1759 /** |
|
1760 * The base implementation of `_.delay` and `_.defer` which accepts an index |
|
1761 * of where to slice the arguments to provide to `func`. |
|
1762 * |
|
1763 * @private |
|
1764 * @param {Function} func The function to delay. |
|
1765 * @param {number} wait The number of milliseconds to delay invocation. |
|
1766 * @param {Object} args The arguments provide to `func`. |
|
1767 * @returns {number} Returns the timer id. |
|
1768 */ |
|
1769 function baseDelay(func, wait, args) { |
|
1770 if (typeof func != 'function') { |
|
1771 throw new TypeError(FUNC_ERROR_TEXT); |
|
1772 } |
|
1773 return setTimeout(function() { func.apply(undefined, args); }, wait); |
|
1774 } |
|
1775 |
|
1776 /** |
|
1777 * The base implementation of `_.difference` which accepts a single array |
|
1778 * of values to exclude. |
|
1779 * |
|
1780 * @private |
|
1781 * @param {Array} array The array to inspect. |
|
1782 * @param {Array} values The values to exclude. |
|
1783 * @returns {Array} Returns the new array of filtered values. |
|
1784 */ |
|
1785 function baseDifference(array, values) { |
|
1786 var length = array ? array.length : 0, |
|
1787 result = []; |
|
1788 |
|
1789 if (!length) { |
|
1790 return result; |
|
1791 } |
|
1792 var index = -1, |
|
1793 indexOf = getIndexOf(), |
|
1794 isCommon = indexOf === baseIndexOf, |
|
1795 cache = (isCommon && values.length >= LARGE_ARRAY_SIZE) ? createCache(values) : null, |
|
1796 valuesLength = values.length; |
|
1797 |
|
1798 if (cache) { |
|
1799 indexOf = cacheIndexOf; |
|
1800 isCommon = false; |
|
1801 values = cache; |
|
1802 } |
|
1803 outer: |
|
1804 while (++index < length) { |
|
1805 var value = array[index]; |
|
1806 |
|
1807 if (isCommon && value === value) { |
|
1808 var valuesIndex = valuesLength; |
|
1809 while (valuesIndex--) { |
|
1810 if (values[valuesIndex] === value) { |
|
1811 continue outer; |
|
1812 } |
847 } |
1813 } |
848 return result || context.Object(); |
1814 result.push(value); |
|
1815 } |
|
1816 else if (indexOf(values, value, 0) < 0) { |
|
1817 result.push(value); |
|
1818 } |
|
1819 } |
|
1820 return result; |
|
1821 } |
|
1822 |
|
1823 /** |
|
1824 * The base implementation of `_.forEach` without support for callback |
|
1825 * shorthands and `this` binding. |
|
1826 * |
|
1827 * @private |
|
1828 * @param {Array|Object|string} collection The collection to iterate over. |
|
1829 * @param {Function} iteratee The function invoked per iteration. |
|
1830 * @returns {Array|Object|string} Returns `collection`. |
|
1831 */ |
|
1832 var baseEach = createBaseEach(baseForOwn); |
|
1833 |
|
1834 /** |
|
1835 * The base implementation of `_.forEachRight` without support for callback |
|
1836 * shorthands and `this` binding. |
|
1837 * |
|
1838 * @private |
|
1839 * @param {Array|Object|string} collection The collection to iterate over. |
|
1840 * @param {Function} iteratee The function invoked per iteration. |
|
1841 * @returns {Array|Object|string} Returns `collection`. |
|
1842 */ |
|
1843 var baseEachRight = createBaseEach(baseForOwnRight, true); |
|
1844 |
|
1845 /** |
|
1846 * The base implementation of `_.every` without support for callback |
|
1847 * shorthands and `this` binding. |
|
1848 * |
|
1849 * @private |
|
1850 * @param {Array|Object|string} collection The collection to iterate over. |
|
1851 * @param {Function} predicate The function invoked per iteration. |
|
1852 * @returns {boolean} Returns `true` if all elements pass the predicate check, |
|
1853 * else `false` |
|
1854 */ |
|
1855 function baseEvery(collection, predicate) { |
|
1856 var result = true; |
|
1857 baseEach(collection, function(value, index, collection) { |
|
1858 result = !!predicate(value, index, collection); |
|
1859 return result; |
|
1860 }); |
|
1861 return result; |
|
1862 } |
|
1863 |
|
1864 /** |
|
1865 * Gets the extremum value of `collection` invoking `iteratee` for each value |
|
1866 * in `collection` to generate the criterion by which the value is ranked. |
|
1867 * The `iteratee` is invoked with three arguments: (value, index|key, collection). |
|
1868 * |
|
1869 * @private |
|
1870 * @param {Array|Object|string} collection The collection to iterate over. |
|
1871 * @param {Function} iteratee The function invoked per iteration. |
|
1872 * @param {Function} comparator The function used to compare values. |
|
1873 * @param {*} exValue The initial extremum value. |
|
1874 * @returns {*} Returns the extremum value. |
|
1875 */ |
|
1876 function baseExtremum(collection, iteratee, comparator, exValue) { |
|
1877 var computed = exValue, |
|
1878 result = computed; |
|
1879 |
|
1880 baseEach(collection, function(value, index, collection) { |
|
1881 var current = +iteratee(value, index, collection); |
|
1882 if (comparator(current, computed) || (current === exValue && current === result)) { |
|
1883 computed = current; |
|
1884 result = value; |
|
1885 } |
|
1886 }); |
|
1887 return result; |
|
1888 } |
|
1889 |
|
1890 /** |
|
1891 * The base implementation of `_.fill` without an iteratee call guard. |
|
1892 * |
|
1893 * @private |
|
1894 * @param {Array} array The array to fill. |
|
1895 * @param {*} value The value to fill `array` with. |
|
1896 * @param {number} [start=0] The start position. |
|
1897 * @param {number} [end=array.length] The end position. |
|
1898 * @returns {Array} Returns `array`. |
|
1899 */ |
|
1900 function baseFill(array, value, start, end) { |
|
1901 var length = array.length; |
|
1902 |
|
1903 start = start == null ? 0 : (+start || 0); |
|
1904 if (start < 0) { |
|
1905 start = -start > length ? 0 : (length + start); |
|
1906 } |
|
1907 end = (end === undefined || end > length) ? length : (+end || 0); |
|
1908 if (end < 0) { |
|
1909 end += length; |
|
1910 } |
|
1911 length = start > end ? 0 : (end >>> 0); |
|
1912 start >>>= 0; |
|
1913 |
|
1914 while (start < length) { |
|
1915 array[start++] = value; |
|
1916 } |
|
1917 return array; |
|
1918 } |
|
1919 |
|
1920 /** |
|
1921 * The base implementation of `_.filter` without support for callback |
|
1922 * shorthands and `this` binding. |
|
1923 * |
|
1924 * @private |
|
1925 * @param {Array|Object|string} collection The collection to iterate over. |
|
1926 * @param {Function} predicate The function invoked per iteration. |
|
1927 * @returns {Array} Returns the new filtered array. |
|
1928 */ |
|
1929 function baseFilter(collection, predicate) { |
|
1930 var result = []; |
|
1931 baseEach(collection, function(value, index, collection) { |
|
1932 if (predicate(value, index, collection)) { |
|
1933 result.push(value); |
|
1934 } |
|
1935 }); |
|
1936 return result; |
|
1937 } |
|
1938 |
|
1939 /** |
|
1940 * The base implementation of `_.find`, `_.findLast`, `_.findKey`, and `_.findLastKey`, |
|
1941 * without support for callback shorthands and `this` binding, which iterates |
|
1942 * over `collection` using the provided `eachFunc`. |
|
1943 * |
|
1944 * @private |
|
1945 * @param {Array|Object|string} collection The collection to search. |
|
1946 * @param {Function} predicate The function invoked per iteration. |
|
1947 * @param {Function} eachFunc The function to iterate over `collection`. |
|
1948 * @param {boolean} [retKey] Specify returning the key of the found element |
|
1949 * instead of the element itself. |
|
1950 * @returns {*} Returns the found element or its key, else `undefined`. |
|
1951 */ |
|
1952 function baseFind(collection, predicate, eachFunc, retKey) { |
|
1953 var result; |
|
1954 eachFunc(collection, function(value, key, collection) { |
|
1955 if (predicate(value, key, collection)) { |
|
1956 result = retKey ? key : value; |
|
1957 return false; |
|
1958 } |
|
1959 }); |
|
1960 return result; |
|
1961 } |
|
1962 |
|
1963 /** |
|
1964 * The base implementation of `_.flatten` with added support for restricting |
|
1965 * flattening and specifying the start index. |
|
1966 * |
|
1967 * @private |
|
1968 * @param {Array} array The array to flatten. |
|
1969 * @param {boolean} [isDeep] Specify a deep flatten. |
|
1970 * @param {boolean} [isStrict] Restrict flattening to arrays-like objects. |
|
1971 * @param {Array} [result=[]] The initial result value. |
|
1972 * @returns {Array} Returns the new flattened array. |
|
1973 */ |
|
1974 function baseFlatten(array, isDeep, isStrict, result) { |
|
1975 result || (result = []); |
|
1976 |
|
1977 var index = -1, |
|
1978 length = array.length; |
|
1979 |
|
1980 while (++index < length) { |
|
1981 var value = array[index]; |
|
1982 if (isObjectLike(value) && isArrayLike(value) && |
|
1983 (isStrict || isArray(value) || isArguments(value))) { |
|
1984 if (isDeep) { |
|
1985 // Recursively flatten arrays (susceptible to call stack limits). |
|
1986 baseFlatten(value, isDeep, isStrict, result); |
|
1987 } else { |
|
1988 arrayPush(result, value); |
|
1989 } |
|
1990 } else if (!isStrict) { |
|
1991 result[result.length] = value; |
|
1992 } |
|
1993 } |
|
1994 return result; |
|
1995 } |
|
1996 |
|
1997 /** |
|
1998 * The base implementation of `baseForIn` and `baseForOwn` which iterates |
|
1999 * over `object` properties returned by `keysFunc` invoking `iteratee` for |
|
2000 * each property. Iteratee functions may exit iteration early by explicitly |
|
2001 * returning `false`. |
|
2002 * |
|
2003 * @private |
|
2004 * @param {Object} object The object to iterate over. |
|
2005 * @param {Function} iteratee The function invoked per iteration. |
|
2006 * @param {Function} keysFunc The function to get the keys of `object`. |
|
2007 * @returns {Object} Returns `object`. |
|
2008 */ |
|
2009 var baseFor = createBaseFor(); |
|
2010 |
|
2011 /** |
|
2012 * This function is like `baseFor` except that it iterates over properties |
|
2013 * in the opposite order. |
|
2014 * |
|
2015 * @private |
|
2016 * @param {Object} object The object to iterate over. |
|
2017 * @param {Function} iteratee The function invoked per iteration. |
|
2018 * @param {Function} keysFunc The function to get the keys of `object`. |
|
2019 * @returns {Object} Returns `object`. |
|
2020 */ |
|
2021 var baseForRight = createBaseFor(true); |
|
2022 |
|
2023 /** |
|
2024 * The base implementation of `_.forIn` without support for callback |
|
2025 * shorthands and `this` binding. |
|
2026 * |
|
2027 * @private |
|
2028 * @param {Object} object The object to iterate over. |
|
2029 * @param {Function} iteratee The function invoked per iteration. |
|
2030 * @returns {Object} Returns `object`. |
|
2031 */ |
|
2032 function baseForIn(object, iteratee) { |
|
2033 return baseFor(object, iteratee, keysIn); |
|
2034 } |
|
2035 |
|
2036 /** |
|
2037 * The base implementation of `_.forOwn` without support for callback |
|
2038 * shorthands and `this` binding. |
|
2039 * |
|
2040 * @private |
|
2041 * @param {Object} object The object to iterate over. |
|
2042 * @param {Function} iteratee The function invoked per iteration. |
|
2043 * @returns {Object} Returns `object`. |
|
2044 */ |
|
2045 function baseForOwn(object, iteratee) { |
|
2046 return baseFor(object, iteratee, keys); |
|
2047 } |
|
2048 |
|
2049 /** |
|
2050 * The base implementation of `_.forOwnRight` without support for callback |
|
2051 * shorthands and `this` binding. |
|
2052 * |
|
2053 * @private |
|
2054 * @param {Object} object The object to iterate over. |
|
2055 * @param {Function} iteratee The function invoked per iteration. |
|
2056 * @returns {Object} Returns `object`. |
|
2057 */ |
|
2058 function baseForOwnRight(object, iteratee) { |
|
2059 return baseForRight(object, iteratee, keys); |
|
2060 } |
|
2061 |
|
2062 /** |
|
2063 * The base implementation of `_.functions` which creates an array of |
|
2064 * `object` function property names filtered from those provided. |
|
2065 * |
|
2066 * @private |
|
2067 * @param {Object} object The object to inspect. |
|
2068 * @param {Array} props The property names to filter. |
|
2069 * @returns {Array} Returns the new array of filtered property names. |
|
2070 */ |
|
2071 function baseFunctions(object, props) { |
|
2072 var index = -1, |
|
2073 length = props.length, |
|
2074 resIndex = -1, |
|
2075 result = []; |
|
2076 |
|
2077 while (++index < length) { |
|
2078 var key = props[index]; |
|
2079 if (isFunction(object[key])) { |
|
2080 result[++resIndex] = key; |
|
2081 } |
|
2082 } |
|
2083 return result; |
|
2084 } |
|
2085 |
|
2086 /** |
|
2087 * The base implementation of `get` without support for string paths |
|
2088 * and default values. |
|
2089 * |
|
2090 * @private |
|
2091 * @param {Object} object The object to query. |
|
2092 * @param {Array} path The path of the property to get. |
|
2093 * @param {string} [pathKey] The key representation of path. |
|
2094 * @returns {*} Returns the resolved value. |
|
2095 */ |
|
2096 function baseGet(object, path, pathKey) { |
|
2097 if (object == null) { |
|
2098 return; |
|
2099 } |
|
2100 if (pathKey !== undefined && pathKey in toObject(object)) { |
|
2101 path = [pathKey]; |
|
2102 } |
|
2103 var index = 0, |
|
2104 length = path.length; |
|
2105 |
|
2106 while (object != null && index < length) { |
|
2107 object = object[path[index++]]; |
|
2108 } |
|
2109 return (index && index == length) ? object : undefined; |
|
2110 } |
|
2111 |
|
2112 /** |
|
2113 * The base implementation of `_.isEqual` without support for `this` binding |
|
2114 * `customizer` functions. |
|
2115 * |
|
2116 * @private |
|
2117 * @param {*} value The value to compare. |
|
2118 * @param {*} other The other value to compare. |
|
2119 * @param {Function} [customizer] The function to customize comparing values. |
|
2120 * @param {boolean} [isLoose] Specify performing partial comparisons. |
|
2121 * @param {Array} [stackA] Tracks traversed `value` objects. |
|
2122 * @param {Array} [stackB] Tracks traversed `other` objects. |
|
2123 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
2124 */ |
|
2125 function baseIsEqual(value, other, customizer, isLoose, stackA, stackB) { |
|
2126 if (value === other) { |
|
2127 return true; |
|
2128 } |
|
2129 if (value == null || other == null || (!isObject(value) && !isObjectLike(other))) { |
|
2130 return value !== value && other !== other; |
|
2131 } |
|
2132 return baseIsEqualDeep(value, other, baseIsEqual, customizer, isLoose, stackA, stackB); |
|
2133 } |
|
2134 |
|
2135 /** |
|
2136 * A specialized version of `baseIsEqual` for arrays and objects which performs |
|
2137 * deep comparisons and tracks traversed objects enabling objects with circular |
|
2138 * references to be compared. |
|
2139 * |
|
2140 * @private |
|
2141 * @param {Object} object The object to compare. |
|
2142 * @param {Object} other The other object to compare. |
|
2143 * @param {Function} equalFunc The function to determine equivalents of values. |
|
2144 * @param {Function} [customizer] The function to customize comparing objects. |
|
2145 * @param {boolean} [isLoose] Specify performing partial comparisons. |
|
2146 * @param {Array} [stackA=[]] Tracks traversed `value` objects. |
|
2147 * @param {Array} [stackB=[]] Tracks traversed `other` objects. |
|
2148 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
2149 */ |
|
2150 function baseIsEqualDeep(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
|
2151 var objIsArr = isArray(object), |
|
2152 othIsArr = isArray(other), |
|
2153 objTag = arrayTag, |
|
2154 othTag = arrayTag; |
|
2155 |
|
2156 if (!objIsArr) { |
|
2157 objTag = objToString.call(object); |
|
2158 if (objTag == argsTag) { |
|
2159 objTag = objectTag; |
|
2160 } else if (objTag != objectTag) { |
|
2161 objIsArr = isTypedArray(object); |
|
2162 } |
|
2163 } |
|
2164 if (!othIsArr) { |
|
2165 othTag = objToString.call(other); |
|
2166 if (othTag == argsTag) { |
|
2167 othTag = objectTag; |
|
2168 } else if (othTag != objectTag) { |
|
2169 othIsArr = isTypedArray(other); |
|
2170 } |
|
2171 } |
|
2172 var objIsObj = objTag == objectTag, |
|
2173 othIsObj = othTag == objectTag, |
|
2174 isSameTag = objTag == othTag; |
|
2175 |
|
2176 if (isSameTag && !(objIsArr || objIsObj)) { |
|
2177 return equalByTag(object, other, objTag); |
|
2178 } |
|
2179 if (!isLoose) { |
|
2180 var objIsWrapped = objIsObj && hasOwnProperty.call(object, '__wrapped__'), |
|
2181 othIsWrapped = othIsObj && hasOwnProperty.call(other, '__wrapped__'); |
|
2182 |
|
2183 if (objIsWrapped || othIsWrapped) { |
|
2184 return equalFunc(objIsWrapped ? object.value() : object, othIsWrapped ? other.value() : other, customizer, isLoose, stackA, stackB); |
|
2185 } |
|
2186 } |
|
2187 if (!isSameTag) { |
|
2188 return false; |
|
2189 } |
|
2190 // Assume cyclic values are equal. |
|
2191 // For more information on detecting circular references see https://es5.github.io/#JO. |
|
2192 stackA || (stackA = []); |
|
2193 stackB || (stackB = []); |
|
2194 |
|
2195 var length = stackA.length; |
|
2196 while (length--) { |
|
2197 if (stackA[length] == object) { |
|
2198 return stackB[length] == other; |
|
2199 } |
|
2200 } |
|
2201 // Add `object` and `other` to the stack of traversed objects. |
|
2202 stackA.push(object); |
|
2203 stackB.push(other); |
|
2204 |
|
2205 var result = (objIsArr ? equalArrays : equalObjects)(object, other, equalFunc, customizer, isLoose, stackA, stackB); |
|
2206 |
|
2207 stackA.pop(); |
|
2208 stackB.pop(); |
|
2209 |
|
2210 return result; |
|
2211 } |
|
2212 |
|
2213 /** |
|
2214 * The base implementation of `_.isMatch` without support for callback |
|
2215 * shorthands and `this` binding. |
|
2216 * |
|
2217 * @private |
|
2218 * @param {Object} object The object to inspect. |
|
2219 * @param {Array} matchData The propery names, values, and compare flags to match. |
|
2220 * @param {Function} [customizer] The function to customize comparing objects. |
|
2221 * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
|
2222 */ |
|
2223 function baseIsMatch(object, matchData, customizer) { |
|
2224 var index = matchData.length, |
|
2225 length = index, |
|
2226 noCustomizer = !customizer; |
|
2227 |
|
2228 if (object == null) { |
|
2229 return !length; |
|
2230 } |
|
2231 object = toObject(object); |
|
2232 while (index--) { |
|
2233 var data = matchData[index]; |
|
2234 if ((noCustomizer && data[2]) |
|
2235 ? data[1] !== object[data[0]] |
|
2236 : !(data[0] in object) |
|
2237 ) { |
|
2238 return false; |
|
2239 } |
|
2240 } |
|
2241 while (++index < length) { |
|
2242 data = matchData[index]; |
|
2243 var key = data[0], |
|
2244 objValue = object[key], |
|
2245 srcValue = data[1]; |
|
2246 |
|
2247 if (noCustomizer && data[2]) { |
|
2248 if (objValue === undefined && !(key in object)) { |
|
2249 return false; |
|
2250 } |
|
2251 } else { |
|
2252 var result = customizer ? customizer(objValue, srcValue, key) : undefined; |
|
2253 if (!(result === undefined ? baseIsEqual(srcValue, objValue, customizer, true) : result)) { |
|
2254 return false; |
|
2255 } |
|
2256 } |
|
2257 } |
|
2258 return true; |
|
2259 } |
|
2260 |
|
2261 /** |
|
2262 * The base implementation of `_.map` without support for callback shorthands |
|
2263 * and `this` binding. |
|
2264 * |
|
2265 * @private |
|
2266 * @param {Array|Object|string} collection The collection to iterate over. |
|
2267 * @param {Function} iteratee The function invoked per iteration. |
|
2268 * @returns {Array} Returns the new mapped array. |
|
2269 */ |
|
2270 function baseMap(collection, iteratee) { |
|
2271 var index = -1, |
|
2272 result = isArrayLike(collection) ? Array(collection.length) : []; |
|
2273 |
|
2274 baseEach(collection, function(value, key, collection) { |
|
2275 result[++index] = iteratee(value, key, collection); |
|
2276 }); |
|
2277 return result; |
|
2278 } |
|
2279 |
|
2280 /** |
|
2281 * The base implementation of `_.matches` which does not clone `source`. |
|
2282 * |
|
2283 * @private |
|
2284 * @param {Object} source The object of property values to match. |
|
2285 * @returns {Function} Returns the new function. |
|
2286 */ |
|
2287 function baseMatches(source) { |
|
2288 var matchData = getMatchData(source); |
|
2289 if (matchData.length == 1 && matchData[0][2]) { |
|
2290 var key = matchData[0][0], |
|
2291 value = matchData[0][1]; |
|
2292 |
|
2293 return function(object) { |
|
2294 if (object == null) { |
|
2295 return false; |
|
2296 } |
|
2297 return object[key] === value && (value !== undefined || (key in toObject(object))); |
849 }; |
2298 }; |
850 }()); |
2299 } |
851 } |
2300 return function(object) { |
852 |
2301 return baseIsMatch(object, matchData); |
853 /** |
2302 }; |
854 * The base implementation of `_.createCallback` without support for creating |
2303 } |
855 * "_.pluck" or "_.where" style callbacks. |
2304 |
856 * |
2305 /** |
857 * @private |
2306 * The base implementation of `_.matchesProperty` which does not clone `srcValue`. |
858 * @param {*} [func=identity] The value to convert to a callback. |
2307 * |
859 * @param {*} [thisArg] The `this` binding of the created callback. |
2308 * @private |
860 * @param {number} [argCount] The number of arguments the callback accepts. |
2309 * @param {string} path The path of the property to get. |
861 * @returns {Function} Returns a callback function. |
2310 * @param {*} srcValue The value to compare. |
862 */ |
2311 * @returns {Function} Returns the new function. |
863 function baseCreateCallback(func, thisArg, argCount) { |
2312 */ |
|
2313 function baseMatchesProperty(path, srcValue) { |
|
2314 var isArr = isArray(path), |
|
2315 isCommon = isKey(path) && isStrictComparable(srcValue), |
|
2316 pathKey = (path + ''); |
|
2317 |
|
2318 path = toPath(path); |
|
2319 return function(object) { |
|
2320 if (object == null) { |
|
2321 return false; |
|
2322 } |
|
2323 var key = pathKey; |
|
2324 object = toObject(object); |
|
2325 if ((isArr || !isCommon) && !(key in object)) { |
|
2326 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
|
2327 if (object == null) { |
|
2328 return false; |
|
2329 } |
|
2330 key = last(path); |
|
2331 object = toObject(object); |
|
2332 } |
|
2333 return object[key] === srcValue |
|
2334 ? (srcValue !== undefined || (key in object)) |
|
2335 : baseIsEqual(srcValue, object[key], undefined, true); |
|
2336 }; |
|
2337 } |
|
2338 |
|
2339 /** |
|
2340 * The base implementation of `_.merge` without support for argument juggling, |
|
2341 * multiple sources, and `this` binding `customizer` functions. |
|
2342 * |
|
2343 * @private |
|
2344 * @param {Object} object The destination object. |
|
2345 * @param {Object} source The source object. |
|
2346 * @param {Function} [customizer] The function to customize merged values. |
|
2347 * @param {Array} [stackA=[]] Tracks traversed source objects. |
|
2348 * @param {Array} [stackB=[]] Associates values with source counterparts. |
|
2349 * @returns {Object} Returns `object`. |
|
2350 */ |
|
2351 function baseMerge(object, source, customizer, stackA, stackB) { |
|
2352 if (!isObject(object)) { |
|
2353 return object; |
|
2354 } |
|
2355 var isSrcArr = isArrayLike(source) && (isArray(source) || isTypedArray(source)), |
|
2356 props = isSrcArr ? undefined : keys(source); |
|
2357 |
|
2358 arrayEach(props || source, function(srcValue, key) { |
|
2359 if (props) { |
|
2360 key = srcValue; |
|
2361 srcValue = source[key]; |
|
2362 } |
|
2363 if (isObjectLike(srcValue)) { |
|
2364 stackA || (stackA = []); |
|
2365 stackB || (stackB = []); |
|
2366 baseMergeDeep(object, source, key, baseMerge, customizer, stackA, stackB); |
|
2367 } |
|
2368 else { |
|
2369 var value = object[key], |
|
2370 result = customizer ? customizer(value, srcValue, key, object, source) : undefined, |
|
2371 isCommon = result === undefined; |
|
2372 |
|
2373 if (isCommon) { |
|
2374 result = srcValue; |
|
2375 } |
|
2376 if ((result !== undefined || (isSrcArr && !(key in object))) && |
|
2377 (isCommon || (result === result ? (result !== value) : (value === value)))) { |
|
2378 object[key] = result; |
|
2379 } |
|
2380 } |
|
2381 }); |
|
2382 return object; |
|
2383 } |
|
2384 |
|
2385 /** |
|
2386 * A specialized version of `baseMerge` for arrays and objects which performs |
|
2387 * deep merges and tracks traversed objects enabling objects with circular |
|
2388 * references to be merged. |
|
2389 * |
|
2390 * @private |
|
2391 * @param {Object} object The destination object. |
|
2392 * @param {Object} source The source object. |
|
2393 * @param {string} key The key of the value to merge. |
|
2394 * @param {Function} mergeFunc The function to merge values. |
|
2395 * @param {Function} [customizer] The function to customize merged values. |
|
2396 * @param {Array} [stackA=[]] Tracks traversed source objects. |
|
2397 * @param {Array} [stackB=[]] Associates values with source counterparts. |
|
2398 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
2399 */ |
|
2400 function baseMergeDeep(object, source, key, mergeFunc, customizer, stackA, stackB) { |
|
2401 var length = stackA.length, |
|
2402 srcValue = source[key]; |
|
2403 |
|
2404 while (length--) { |
|
2405 if (stackA[length] == srcValue) { |
|
2406 object[key] = stackB[length]; |
|
2407 return; |
|
2408 } |
|
2409 } |
|
2410 var value = object[key], |
|
2411 result = customizer ? customizer(value, srcValue, key, object, source) : undefined, |
|
2412 isCommon = result === undefined; |
|
2413 |
|
2414 if (isCommon) { |
|
2415 result = srcValue; |
|
2416 if (isArrayLike(srcValue) && (isArray(srcValue) || isTypedArray(srcValue))) { |
|
2417 result = isArray(value) |
|
2418 ? value |
|
2419 : (isArrayLike(value) ? arrayCopy(value) : []); |
|
2420 } |
|
2421 else if (isPlainObject(srcValue) || isArguments(srcValue)) { |
|
2422 result = isArguments(value) |
|
2423 ? toPlainObject(value) |
|
2424 : (isPlainObject(value) ? value : {}); |
|
2425 } |
|
2426 else { |
|
2427 isCommon = false; |
|
2428 } |
|
2429 } |
|
2430 // Add the source value to the stack of traversed objects and associate |
|
2431 // it with its merged value. |
|
2432 stackA.push(srcValue); |
|
2433 stackB.push(result); |
|
2434 |
|
2435 if (isCommon) { |
|
2436 // Recursively merge objects and arrays (susceptible to call stack limits). |
|
2437 object[key] = mergeFunc(result, srcValue, customizer, stackA, stackB); |
|
2438 } else if (result === result ? (result !== value) : (value === value)) { |
|
2439 object[key] = result; |
|
2440 } |
|
2441 } |
|
2442 |
|
2443 /** |
|
2444 * The base implementation of `_.property` without support for deep paths. |
|
2445 * |
|
2446 * @private |
|
2447 * @param {string} key The key of the property to get. |
|
2448 * @returns {Function} Returns the new function. |
|
2449 */ |
|
2450 function baseProperty(key) { |
|
2451 return function(object) { |
|
2452 return object == null ? undefined : object[key]; |
|
2453 }; |
|
2454 } |
|
2455 |
|
2456 /** |
|
2457 * A specialized version of `baseProperty` which supports deep paths. |
|
2458 * |
|
2459 * @private |
|
2460 * @param {Array|string} path The path of the property to get. |
|
2461 * @returns {Function} Returns the new function. |
|
2462 */ |
|
2463 function basePropertyDeep(path) { |
|
2464 var pathKey = (path + ''); |
|
2465 path = toPath(path); |
|
2466 return function(object) { |
|
2467 return baseGet(object, path, pathKey); |
|
2468 }; |
|
2469 } |
|
2470 |
|
2471 /** |
|
2472 * The base implementation of `_.pullAt` without support for individual |
|
2473 * index arguments and capturing the removed elements. |
|
2474 * |
|
2475 * @private |
|
2476 * @param {Array} array The array to modify. |
|
2477 * @param {number[]} indexes The indexes of elements to remove. |
|
2478 * @returns {Array} Returns `array`. |
|
2479 */ |
|
2480 function basePullAt(array, indexes) { |
|
2481 var length = array ? indexes.length : 0; |
|
2482 while (length--) { |
|
2483 var index = indexes[length]; |
|
2484 if (index != previous && isIndex(index)) { |
|
2485 var previous = index; |
|
2486 splice.call(array, index, 1); |
|
2487 } |
|
2488 } |
|
2489 return array; |
|
2490 } |
|
2491 |
|
2492 /** |
|
2493 * The base implementation of `_.random` without support for argument juggling |
|
2494 * and returning floating-point numbers. |
|
2495 * |
|
2496 * @private |
|
2497 * @param {number} min The minimum possible value. |
|
2498 * @param {number} max The maximum possible value. |
|
2499 * @returns {number} Returns the random number. |
|
2500 */ |
|
2501 function baseRandom(min, max) { |
|
2502 return min + nativeFloor(nativeRandom() * (max - min + 1)); |
|
2503 } |
|
2504 |
|
2505 /** |
|
2506 * The base implementation of `_.reduce` and `_.reduceRight` without support |
|
2507 * for callback shorthands and `this` binding, which iterates over `collection` |
|
2508 * using the provided `eachFunc`. |
|
2509 * |
|
2510 * @private |
|
2511 * @param {Array|Object|string} collection The collection to iterate over. |
|
2512 * @param {Function} iteratee The function invoked per iteration. |
|
2513 * @param {*} accumulator The initial value. |
|
2514 * @param {boolean} initFromCollection Specify using the first or last element |
|
2515 * of `collection` as the initial value. |
|
2516 * @param {Function} eachFunc The function to iterate over `collection`. |
|
2517 * @returns {*} Returns the accumulated value. |
|
2518 */ |
|
2519 function baseReduce(collection, iteratee, accumulator, initFromCollection, eachFunc) { |
|
2520 eachFunc(collection, function(value, index, collection) { |
|
2521 accumulator = initFromCollection |
|
2522 ? (initFromCollection = false, value) |
|
2523 : iteratee(accumulator, value, index, collection); |
|
2524 }); |
|
2525 return accumulator; |
|
2526 } |
|
2527 |
|
2528 /** |
|
2529 * The base implementation of `setData` without support for hot loop detection. |
|
2530 * |
|
2531 * @private |
|
2532 * @param {Function} func The function to associate metadata with. |
|
2533 * @param {*} data The metadata. |
|
2534 * @returns {Function} Returns `func`. |
|
2535 */ |
|
2536 var baseSetData = !metaMap ? identity : function(func, data) { |
|
2537 metaMap.set(func, data); |
|
2538 return func; |
|
2539 }; |
|
2540 |
|
2541 /** |
|
2542 * The base implementation of `_.slice` without an iteratee call guard. |
|
2543 * |
|
2544 * @private |
|
2545 * @param {Array} array The array to slice. |
|
2546 * @param {number} [start=0] The start position. |
|
2547 * @param {number} [end=array.length] The end position. |
|
2548 * @returns {Array} Returns the slice of `array`. |
|
2549 */ |
|
2550 function baseSlice(array, start, end) { |
|
2551 var index = -1, |
|
2552 length = array.length; |
|
2553 |
|
2554 start = start == null ? 0 : (+start || 0); |
|
2555 if (start < 0) { |
|
2556 start = -start > length ? 0 : (length + start); |
|
2557 } |
|
2558 end = (end === undefined || end > length) ? length : (+end || 0); |
|
2559 if (end < 0) { |
|
2560 end += length; |
|
2561 } |
|
2562 length = start > end ? 0 : ((end - start) >>> 0); |
|
2563 start >>>= 0; |
|
2564 |
|
2565 var result = Array(length); |
|
2566 while (++index < length) { |
|
2567 result[index] = array[index + start]; |
|
2568 } |
|
2569 return result; |
|
2570 } |
|
2571 |
|
2572 /** |
|
2573 * The base implementation of `_.some` without support for callback shorthands |
|
2574 * and `this` binding. |
|
2575 * |
|
2576 * @private |
|
2577 * @param {Array|Object|string} collection The collection to iterate over. |
|
2578 * @param {Function} predicate The function invoked per iteration. |
|
2579 * @returns {boolean} Returns `true` if any element passes the predicate check, |
|
2580 * else `false`. |
|
2581 */ |
|
2582 function baseSome(collection, predicate) { |
|
2583 var result; |
|
2584 |
|
2585 baseEach(collection, function(value, index, collection) { |
|
2586 result = predicate(value, index, collection); |
|
2587 return !result; |
|
2588 }); |
|
2589 return !!result; |
|
2590 } |
|
2591 |
|
2592 /** |
|
2593 * The base implementation of `_.sortBy` which uses `comparer` to define |
|
2594 * the sort order of `array` and replaces criteria objects with their |
|
2595 * corresponding values. |
|
2596 * |
|
2597 * @private |
|
2598 * @param {Array} array The array to sort. |
|
2599 * @param {Function} comparer The function to define sort order. |
|
2600 * @returns {Array} Returns `array`. |
|
2601 */ |
|
2602 function baseSortBy(array, comparer) { |
|
2603 var length = array.length; |
|
2604 |
|
2605 array.sort(comparer); |
|
2606 while (length--) { |
|
2607 array[length] = array[length].value; |
|
2608 } |
|
2609 return array; |
|
2610 } |
|
2611 |
|
2612 /** |
|
2613 * The base implementation of `_.sortByOrder` without param guards. |
|
2614 * |
|
2615 * @private |
|
2616 * @param {Array|Object|string} collection The collection to iterate over. |
|
2617 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
|
2618 * @param {boolean[]} orders The sort orders of `iteratees`. |
|
2619 * @returns {Array} Returns the new sorted array. |
|
2620 */ |
|
2621 function baseSortByOrder(collection, iteratees, orders) { |
|
2622 var callback = getCallback(), |
|
2623 index = -1; |
|
2624 |
|
2625 iteratees = arrayMap(iteratees, function(iteratee) { return callback(iteratee); }); |
|
2626 |
|
2627 var result = baseMap(collection, function(value) { |
|
2628 var criteria = arrayMap(iteratees, function(iteratee) { return iteratee(value); }); |
|
2629 return { 'criteria': criteria, 'index': ++index, 'value': value }; |
|
2630 }); |
|
2631 |
|
2632 return baseSortBy(result, function(object, other) { |
|
2633 return compareMultiple(object, other, orders); |
|
2634 }); |
|
2635 } |
|
2636 |
|
2637 /** |
|
2638 * The base implementation of `_.sum` without support for callback shorthands |
|
2639 * and `this` binding. |
|
2640 * |
|
2641 * @private |
|
2642 * @param {Array|Object|string} collection The collection to iterate over. |
|
2643 * @param {Function} iteratee The function invoked per iteration. |
|
2644 * @returns {number} Returns the sum. |
|
2645 */ |
|
2646 function baseSum(collection, iteratee) { |
|
2647 var result = 0; |
|
2648 baseEach(collection, function(value, index, collection) { |
|
2649 result += +iteratee(value, index, collection) || 0; |
|
2650 }); |
|
2651 return result; |
|
2652 } |
|
2653 |
|
2654 /** |
|
2655 * The base implementation of `_.uniq` without support for callback shorthands |
|
2656 * and `this` binding. |
|
2657 * |
|
2658 * @private |
|
2659 * @param {Array} array The array to inspect. |
|
2660 * @param {Function} [iteratee] The function invoked per iteration. |
|
2661 * @returns {Array} Returns the new duplicate free array. |
|
2662 */ |
|
2663 function baseUniq(array, iteratee) { |
|
2664 var index = -1, |
|
2665 indexOf = getIndexOf(), |
|
2666 length = array.length, |
|
2667 isCommon = indexOf === baseIndexOf, |
|
2668 isLarge = isCommon && length >= LARGE_ARRAY_SIZE, |
|
2669 seen = isLarge ? createCache() : null, |
|
2670 result = []; |
|
2671 |
|
2672 if (seen) { |
|
2673 indexOf = cacheIndexOf; |
|
2674 isCommon = false; |
|
2675 } else { |
|
2676 isLarge = false; |
|
2677 seen = iteratee ? [] : result; |
|
2678 } |
|
2679 outer: |
|
2680 while (++index < length) { |
|
2681 var value = array[index], |
|
2682 computed = iteratee ? iteratee(value, index, array) : value; |
|
2683 |
|
2684 if (isCommon && value === value) { |
|
2685 var seenIndex = seen.length; |
|
2686 while (seenIndex--) { |
|
2687 if (seen[seenIndex] === computed) { |
|
2688 continue outer; |
|
2689 } |
|
2690 } |
|
2691 if (iteratee) { |
|
2692 seen.push(computed); |
|
2693 } |
|
2694 result.push(value); |
|
2695 } |
|
2696 else if (indexOf(seen, computed, 0) < 0) { |
|
2697 if (iteratee || isLarge) { |
|
2698 seen.push(computed); |
|
2699 } |
|
2700 result.push(value); |
|
2701 } |
|
2702 } |
|
2703 return result; |
|
2704 } |
|
2705 |
|
2706 /** |
|
2707 * The base implementation of `_.values` and `_.valuesIn` which creates an |
|
2708 * array of `object` property values corresponding to the property names |
|
2709 * of `props`. |
|
2710 * |
|
2711 * @private |
|
2712 * @param {Object} object The object to query. |
|
2713 * @param {Array} props The property names to get values for. |
|
2714 * @returns {Object} Returns the array of property values. |
|
2715 */ |
|
2716 function baseValues(object, props) { |
|
2717 var index = -1, |
|
2718 length = props.length, |
|
2719 result = Array(length); |
|
2720 |
|
2721 while (++index < length) { |
|
2722 result[index] = object[props[index]]; |
|
2723 } |
|
2724 return result; |
|
2725 } |
|
2726 |
|
2727 /** |
|
2728 * The base implementation of `_.dropRightWhile`, `_.dropWhile`, `_.takeRightWhile`, |
|
2729 * and `_.takeWhile` without support for callback shorthands and `this` binding. |
|
2730 * |
|
2731 * @private |
|
2732 * @param {Array} array The array to query. |
|
2733 * @param {Function} predicate The function invoked per iteration. |
|
2734 * @param {boolean} [isDrop] Specify dropping elements instead of taking them. |
|
2735 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
2736 * @returns {Array} Returns the slice of `array`. |
|
2737 */ |
|
2738 function baseWhile(array, predicate, isDrop, fromRight) { |
|
2739 var length = array.length, |
|
2740 index = fromRight ? length : -1; |
|
2741 |
|
2742 while ((fromRight ? index-- : ++index < length) && predicate(array[index], index, array)) {} |
|
2743 return isDrop |
|
2744 ? baseSlice(array, (fromRight ? 0 : index), (fromRight ? index + 1 : length)) |
|
2745 : baseSlice(array, (fromRight ? index + 1 : 0), (fromRight ? length : index)); |
|
2746 } |
|
2747 |
|
2748 /** |
|
2749 * The base implementation of `wrapperValue` which returns the result of |
|
2750 * performing a sequence of actions on the unwrapped `value`, where each |
|
2751 * successive action is supplied the return value of the previous. |
|
2752 * |
|
2753 * @private |
|
2754 * @param {*} value The unwrapped value. |
|
2755 * @param {Array} actions Actions to peform to resolve the unwrapped value. |
|
2756 * @returns {*} Returns the resolved value. |
|
2757 */ |
|
2758 function baseWrapperValue(value, actions) { |
|
2759 var result = value; |
|
2760 if (result instanceof LazyWrapper) { |
|
2761 result = result.value(); |
|
2762 } |
|
2763 var index = -1, |
|
2764 length = actions.length; |
|
2765 |
|
2766 while (++index < length) { |
|
2767 var action = actions[index]; |
|
2768 result = action.func.apply(action.thisArg, arrayPush([result], action.args)); |
|
2769 } |
|
2770 return result; |
|
2771 } |
|
2772 |
|
2773 /** |
|
2774 * Performs a binary search of `array` to determine the index at which `value` |
|
2775 * should be inserted into `array` in order to maintain its sort order. |
|
2776 * |
|
2777 * @private |
|
2778 * @param {Array} array The sorted array to inspect. |
|
2779 * @param {*} value The value to evaluate. |
|
2780 * @param {boolean} [retHighest] Specify returning the highest qualified index. |
|
2781 * @returns {number} Returns the index at which `value` should be inserted |
|
2782 * into `array`. |
|
2783 */ |
|
2784 function binaryIndex(array, value, retHighest) { |
|
2785 var low = 0, |
|
2786 high = array ? array.length : low; |
|
2787 |
|
2788 if (typeof value == 'number' && value === value && high <= HALF_MAX_ARRAY_LENGTH) { |
|
2789 while (low < high) { |
|
2790 var mid = (low + high) >>> 1, |
|
2791 computed = array[mid]; |
|
2792 |
|
2793 if ((retHighest ? (computed <= value) : (computed < value)) && computed !== null) { |
|
2794 low = mid + 1; |
|
2795 } else { |
|
2796 high = mid; |
|
2797 } |
|
2798 } |
|
2799 return high; |
|
2800 } |
|
2801 return binaryIndexBy(array, value, identity, retHighest); |
|
2802 } |
|
2803 |
|
2804 /** |
|
2805 * This function is like `binaryIndex` except that it invokes `iteratee` for |
|
2806 * `value` and each element of `array` to compute their sort ranking. The |
|
2807 * iteratee is invoked with one argument; (value). |
|
2808 * |
|
2809 * @private |
|
2810 * @param {Array} array The sorted array to inspect. |
|
2811 * @param {*} value The value to evaluate. |
|
2812 * @param {Function} iteratee The function invoked per iteration. |
|
2813 * @param {boolean} [retHighest] Specify returning the highest qualified index. |
|
2814 * @returns {number} Returns the index at which `value` should be inserted |
|
2815 * into `array`. |
|
2816 */ |
|
2817 function binaryIndexBy(array, value, iteratee, retHighest) { |
|
2818 value = iteratee(value); |
|
2819 |
|
2820 var low = 0, |
|
2821 high = array ? array.length : 0, |
|
2822 valIsNaN = value !== value, |
|
2823 valIsNull = value === null, |
|
2824 valIsUndef = value === undefined; |
|
2825 |
|
2826 while (low < high) { |
|
2827 var mid = nativeFloor((low + high) / 2), |
|
2828 computed = iteratee(array[mid]), |
|
2829 isDef = computed !== undefined, |
|
2830 isReflexive = computed === computed; |
|
2831 |
|
2832 if (valIsNaN) { |
|
2833 var setLow = isReflexive || retHighest; |
|
2834 } else if (valIsNull) { |
|
2835 setLow = isReflexive && isDef && (retHighest || computed != null); |
|
2836 } else if (valIsUndef) { |
|
2837 setLow = isReflexive && (retHighest || isDef); |
|
2838 } else if (computed == null) { |
|
2839 setLow = false; |
|
2840 } else { |
|
2841 setLow = retHighest ? (computed <= value) : (computed < value); |
|
2842 } |
|
2843 if (setLow) { |
|
2844 low = mid + 1; |
|
2845 } else { |
|
2846 high = mid; |
|
2847 } |
|
2848 } |
|
2849 return nativeMin(high, MAX_ARRAY_INDEX); |
|
2850 } |
|
2851 |
|
2852 /** |
|
2853 * A specialized version of `baseCallback` which only supports `this` binding |
|
2854 * and specifying the number of arguments to provide to `func`. |
|
2855 * |
|
2856 * @private |
|
2857 * @param {Function} func The function to bind. |
|
2858 * @param {*} thisArg The `this` binding of `func`. |
|
2859 * @param {number} [argCount] The number of arguments to provide to `func`. |
|
2860 * @returns {Function} Returns the callback. |
|
2861 */ |
|
2862 function bindCallback(func, thisArg, argCount) { |
864 if (typeof func != 'function') { |
2863 if (typeof func != 'function') { |
865 return identity; |
2864 return identity; |
866 } |
2865 } |
867 // exit early for no `thisArg` or already bound by `Function#bind` |
2866 if (thisArg === undefined) { |
868 if (typeof thisArg == 'undefined' || !('prototype' in func)) { |
|
869 return func; |
|
870 } |
|
871 var bindData = func.__bindData__; |
|
872 if (typeof bindData == 'undefined') { |
|
873 if (support.funcNames) { |
|
874 bindData = !func.name; |
|
875 } |
|
876 bindData = bindData || !support.funcDecomp; |
|
877 if (!bindData) { |
|
878 var source = fnToString.call(func); |
|
879 if (!support.funcNames) { |
|
880 bindData = !reFuncName.test(source); |
|
881 } |
|
882 if (!bindData) { |
|
883 // checks if `func` references the `this` keyword and stores the result |
|
884 bindData = reThis.test(source); |
|
885 setBindData(func, bindData); |
|
886 } |
|
887 } |
|
888 } |
|
889 // exit early if there are no `this` references or `func` is bound |
|
890 if (bindData === false || (bindData !== true && bindData[1] & 1)) { |
|
891 return func; |
2867 return func; |
892 } |
2868 } |
893 switch (argCount) { |
2869 switch (argCount) { |
894 case 1: return function(value) { |
2870 case 1: return function(value) { |
895 return func.call(thisArg, value); |
2871 return func.call(thisArg, value); |
896 }; |
|
897 case 2: return function(a, b) { |
|
898 return func.call(thisArg, a, b); |
|
899 }; |
2872 }; |
900 case 3: return function(value, index, collection) { |
2873 case 3: return function(value, index, collection) { |
901 return func.call(thisArg, value, index, collection); |
2874 return func.call(thisArg, value, index, collection); |
902 }; |
2875 }; |
903 case 4: return function(accumulator, value, index, collection) { |
2876 case 4: return function(accumulator, value, index, collection) { |
904 return func.call(thisArg, accumulator, value, index, collection); |
2877 return func.call(thisArg, accumulator, value, index, collection); |
905 }; |
2878 }; |
906 } |
2879 case 5: return function(value, other, key, object, source) { |
907 return bind(func, thisArg); |
2880 return func.call(thisArg, value, other, key, object, source); |
908 } |
2881 }; |
909 |
2882 } |
910 /** |
2883 return function() { |
911 * The base implementation of `createWrapper` that creates the wrapper and |
2884 return func.apply(thisArg, arguments); |
912 * sets its meta data. |
2885 }; |
913 * |
2886 } |
914 * @private |
2887 |
915 * @param {Array} bindData The bind data array. |
2888 /** |
916 * @returns {Function} Returns the new function. |
2889 * Creates a clone of the given array buffer. |
917 */ |
2890 * |
918 function baseCreateWrapper(bindData) { |
2891 * @private |
919 var func = bindData[0], |
2892 * @param {ArrayBuffer} buffer The array buffer to clone. |
920 bitmask = bindData[1], |
2893 * @returns {ArrayBuffer} Returns the cloned array buffer. |
921 partialArgs = bindData[2], |
2894 */ |
922 partialRightArgs = bindData[3], |
2895 function bufferClone(buffer) { |
923 thisArg = bindData[4], |
2896 var result = new ArrayBuffer(buffer.byteLength), |
924 arity = bindData[5]; |
2897 view = new Uint8Array(result); |
925 |
2898 |
926 var isBind = bitmask & 1, |
2899 view.set(new Uint8Array(buffer)); |
927 isBindKey = bitmask & 2, |
|
928 isCurry = bitmask & 4, |
|
929 isCurryBound = bitmask & 8, |
|
930 key = func; |
|
931 |
|
932 function bound() { |
|
933 var thisBinding = isBind ? thisArg : this; |
|
934 if (partialArgs) { |
|
935 var args = slice(partialArgs); |
|
936 push.apply(args, arguments); |
|
937 } |
|
938 if (partialRightArgs || isCurry) { |
|
939 args || (args = slice(arguments)); |
|
940 if (partialRightArgs) { |
|
941 push.apply(args, partialRightArgs); |
|
942 } |
|
943 if (isCurry && args.length < arity) { |
|
944 bitmask |= 16 & ~32; |
|
945 return baseCreateWrapper([func, (isCurryBound ? bitmask : bitmask & ~3), args, null, thisArg, arity]); |
|
946 } |
|
947 } |
|
948 args || (args = arguments); |
|
949 if (isBindKey) { |
|
950 func = thisBinding[key]; |
|
951 } |
|
952 if (this instanceof bound) { |
|
953 thisBinding = baseCreate(func.prototype); |
|
954 var result = func.apply(thisBinding, args); |
|
955 return isObject(result) ? result : thisBinding; |
|
956 } |
|
957 return func.apply(thisBinding, args); |
|
958 } |
|
959 setBindData(bound, bindData); |
|
960 return bound; |
|
961 } |
|
962 |
|
963 /** |
|
964 * The base implementation of `_.difference` that accepts a single array |
|
965 * of values to exclude. |
|
966 * |
|
967 * @private |
|
968 * @param {Array} array The array to process. |
|
969 * @param {Array} [values] The array of values to exclude. |
|
970 * @returns {Array} Returns a new array of filtered values. |
|
971 */ |
|
972 function baseDifference(array, values) { |
|
973 var index = -1, |
|
974 indexOf = getIndexOf(), |
|
975 length = array ? array.length : 0, |
|
976 isLarge = length >= largeArraySize && indexOf === baseIndexOf, |
|
977 result = []; |
|
978 |
|
979 if (isLarge) { |
|
980 var cache = createCache(values); |
|
981 if (cache) { |
|
982 indexOf = cacheIndexOf; |
|
983 values = cache; |
|
984 } else { |
|
985 isLarge = false; |
|
986 } |
|
987 } |
|
988 while (++index < length) { |
|
989 var value = array[index]; |
|
990 if (indexOf(values, value) < 0) { |
|
991 result.push(value); |
|
992 } |
|
993 } |
|
994 if (isLarge) { |
|
995 releaseObject(values); |
|
996 } |
|
997 return result; |
2900 return result; |
998 } |
2901 } |
999 |
2902 |
1000 /** |
2903 /** |
1001 * The base implementation of `_.flatten` without support for callback |
2904 * Creates an array that is the composition of partially applied arguments, |
1002 * shorthands or `thisArg` binding. |
2905 * placeholders, and provided arguments into a single array of arguments. |
1003 * |
2906 * |
1004 * @private |
2907 * @private |
1005 * @param {Array} array The array to flatten. |
2908 * @param {Array|Object} args The provided arguments. |
1006 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. |
2909 * @param {Array} partials The arguments to prepend to those provided. |
1007 * @param {boolean} [isStrict=false] A flag to restrict flattening to arrays and `arguments` objects. |
2910 * @param {Array} holders The `partials` placeholder indexes. |
1008 * @param {number} [fromIndex=0] The index to start from. |
2911 * @returns {Array} Returns the new array of composed arguments. |
1009 * @returns {Array} Returns a new flattened array. |
2912 */ |
1010 */ |
2913 function composeArgs(args, partials, holders) { |
1011 function baseFlatten(array, isShallow, isStrict, fromIndex) { |
2914 var holdersLength = holders.length, |
1012 var index = (fromIndex || 0) - 1, |
2915 argsIndex = -1, |
1013 length = array ? array.length : 0, |
2916 argsLength = nativeMax(args.length - holdersLength, 0), |
1014 result = []; |
2917 leftIndex = -1, |
1015 |
2918 leftLength = partials.length, |
1016 while (++index < length) { |
2919 result = Array(leftLength + argsLength); |
1017 var value = array[index]; |
2920 |
1018 |
2921 while (++leftIndex < leftLength) { |
1019 if (value && typeof value == 'object' && typeof value.length == 'number' |
2922 result[leftIndex] = partials[leftIndex]; |
1020 && (isArray(value) || isArguments(value))) { |
2923 } |
1021 // recursively flatten arrays (susceptible to call stack limits) |
2924 while (++argsIndex < holdersLength) { |
1022 if (!isShallow) { |
2925 result[holders[argsIndex]] = args[argsIndex]; |
1023 value = baseFlatten(value, isShallow, isStrict); |
2926 } |
1024 } |
2927 while (argsLength--) { |
1025 var valIndex = -1, |
2928 result[leftIndex++] = args[argsIndex++]; |
1026 valLength = value.length, |
|
1027 resIndex = result.length; |
|
1028 |
|
1029 result.length += valLength; |
|
1030 while (++valIndex < valLength) { |
|
1031 result[resIndex++] = value[valIndex]; |
|
1032 } |
|
1033 } else if (!isStrict) { |
|
1034 result.push(value); |
|
1035 } |
|
1036 } |
2929 } |
1037 return result; |
2930 return result; |
1038 } |
2931 } |
1039 |
2932 |
1040 /** |
2933 /** |
1041 * The base implementation of `_.isEqual`, without support for `thisArg` binding, |
2934 * This function is like `composeArgs` except that the arguments composition |
1042 * that allows partial "_.where" style comparisons. |
2935 * is tailored for `_.partialRight`. |
1043 * |
2936 * |
1044 * @private |
2937 * @private |
1045 * @param {*} a The value to compare. |
2938 * @param {Array|Object} args The provided arguments. |
1046 * @param {*} b The other value to compare. |
2939 * @param {Array} partials The arguments to append to those provided. |
1047 * @param {Function} [callback] The function to customize comparing values. |
2940 * @param {Array} holders The `partials` placeholder indexes. |
1048 * @param {Function} [isWhere=false] A flag to indicate performing partial comparisons. |
2941 * @returns {Array} Returns the new array of composed arguments. |
1049 * @param {Array} [stackA=[]] Tracks traversed `a` objects. |
2942 */ |
1050 * @param {Array} [stackB=[]] Tracks traversed `b` objects. |
2943 function composeArgsRight(args, partials, holders) { |
1051 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
2944 var holdersIndex = -1, |
1052 */ |
2945 holdersLength = holders.length, |
1053 function baseIsEqual(a, b, callback, isWhere, stackA, stackB) { |
2946 argsIndex = -1, |
1054 // used to indicate that when comparing objects, `a` has at least the properties of `b` |
2947 argsLength = nativeMax(args.length - holdersLength, 0), |
1055 if (callback) { |
2948 rightIndex = -1, |
1056 var result = callback(a, b); |
2949 rightLength = partials.length, |
1057 if (typeof result != 'undefined') { |
2950 result = Array(argsLength + rightLength); |
1058 return !!result; |
2951 |
1059 } |
2952 while (++argsIndex < argsLength) { |
1060 } |
2953 result[argsIndex] = args[argsIndex]; |
1061 // exit early for identical values |
2954 } |
1062 if (a === b) { |
2955 var offset = argsIndex; |
1063 // treat `+0` vs. `-0` as not equal |
2956 while (++rightIndex < rightLength) { |
1064 return a !== 0 || (1 / a == 1 / b); |
2957 result[offset + rightIndex] = partials[rightIndex]; |
1065 } |
2958 } |
1066 var type = typeof a, |
2959 while (++holdersIndex < holdersLength) { |
1067 otherType = typeof b; |
2960 result[offset + holders[holdersIndex]] = args[argsIndex++]; |
1068 |
|
1069 // exit early for unlike primitive values |
|
1070 if (a === a && |
|
1071 !(a && objectTypes[type]) && |
|
1072 !(b && objectTypes[otherType])) { |
|
1073 return false; |
|
1074 } |
|
1075 // exit early for `null` and `undefined` avoiding ES3's Function#call behavior |
|
1076 // http://es5.github.io/#x15.3.4.4 |
|
1077 if (a == null || b == null) { |
|
1078 return a === b; |
|
1079 } |
|
1080 // compare [[Class]] names |
|
1081 var className = toString.call(a), |
|
1082 otherClass = toString.call(b); |
|
1083 |
|
1084 if (className == argsClass) { |
|
1085 className = objectClass; |
|
1086 } |
|
1087 if (otherClass == argsClass) { |
|
1088 otherClass = objectClass; |
|
1089 } |
|
1090 if (className != otherClass) { |
|
1091 return false; |
|
1092 } |
|
1093 switch (className) { |
|
1094 case boolClass: |
|
1095 case dateClass: |
|
1096 // coerce dates and booleans to numbers, dates to milliseconds and booleans |
|
1097 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal |
|
1098 return +a == +b; |
|
1099 |
|
1100 case numberClass: |
|
1101 // treat `NaN` vs. `NaN` as equal |
|
1102 return (a != +a) |
|
1103 ? b != +b |
|
1104 // but treat `+0` vs. `-0` as not equal |
|
1105 : (a == 0 ? (1 / a == 1 / b) : a == +b); |
|
1106 |
|
1107 case regexpClass: |
|
1108 case stringClass: |
|
1109 // coerce regexes to strings (http://es5.github.io/#x15.10.6.4) |
|
1110 // treat string primitives and their corresponding object instances as equal |
|
1111 return a == String(b); |
|
1112 } |
|
1113 var isArr = className == arrayClass; |
|
1114 if (!isArr) { |
|
1115 // unwrap any `lodash` wrapped values |
|
1116 var aWrapped = hasOwnProperty.call(a, '__wrapped__'), |
|
1117 bWrapped = hasOwnProperty.call(b, '__wrapped__'); |
|
1118 |
|
1119 if (aWrapped || bWrapped) { |
|
1120 return baseIsEqual(aWrapped ? a.__wrapped__ : a, bWrapped ? b.__wrapped__ : b, callback, isWhere, stackA, stackB); |
|
1121 } |
|
1122 // exit for functions and DOM nodes |
|
1123 if (className != objectClass) { |
|
1124 return false; |
|
1125 } |
|
1126 // in older versions of Opera, `arguments` objects have `Array` constructors |
|
1127 var ctorA = a.constructor, |
|
1128 ctorB = b.constructor; |
|
1129 |
|
1130 // non `Object` object instances with different constructors are not equal |
|
1131 if (ctorA != ctorB && |
|
1132 !(isFunction(ctorA) && ctorA instanceof ctorA && isFunction(ctorB) && ctorB instanceof ctorB) && |
|
1133 ('constructor' in a && 'constructor' in b) |
|
1134 ) { |
|
1135 return false; |
|
1136 } |
|
1137 } |
|
1138 // assume cyclic structures are equal |
|
1139 // the algorithm for detecting cyclic structures is adapted from ES 5.1 |
|
1140 // section 15.12.3, abstract operation `JO` (http://es5.github.io/#x15.12.3) |
|
1141 var initedStack = !stackA; |
|
1142 stackA || (stackA = getArray()); |
|
1143 stackB || (stackB = getArray()); |
|
1144 |
|
1145 var length = stackA.length; |
|
1146 while (length--) { |
|
1147 if (stackA[length] == a) { |
|
1148 return stackB[length] == b; |
|
1149 } |
|
1150 } |
|
1151 var size = 0; |
|
1152 result = true; |
|
1153 |
|
1154 // add `a` and `b` to the stack of traversed objects |
|
1155 stackA.push(a); |
|
1156 stackB.push(b); |
|
1157 |
|
1158 // recursively compare objects and arrays (susceptible to call stack limits) |
|
1159 if (isArr) { |
|
1160 // compare lengths to determine if a deep comparison is necessary |
|
1161 length = a.length; |
|
1162 size = b.length; |
|
1163 result = size == length; |
|
1164 |
|
1165 if (result || isWhere) { |
|
1166 // deep compare the contents, ignoring non-numeric properties |
|
1167 while (size--) { |
|
1168 var index = length, |
|
1169 value = b[size]; |
|
1170 |
|
1171 if (isWhere) { |
|
1172 while (index--) { |
|
1173 if ((result = baseIsEqual(a[index], value, callback, isWhere, stackA, stackB))) { |
|
1174 break; |
|
1175 } |
|
1176 } |
|
1177 } else if (!(result = baseIsEqual(a[size], value, callback, isWhere, stackA, stackB))) { |
|
1178 break; |
|
1179 } |
|
1180 } |
|
1181 } |
|
1182 } |
|
1183 else { |
|
1184 // deep compare objects using `forIn`, instead of `forOwn`, to avoid `Object.keys` |
|
1185 // which, in this case, is more costly |
|
1186 forIn(b, function(value, key, b) { |
|
1187 if (hasOwnProperty.call(b, key)) { |
|
1188 // count the number of properties. |
|
1189 size++; |
|
1190 // deep compare each property value. |
|
1191 return (result = hasOwnProperty.call(a, key) && baseIsEqual(a[key], value, callback, isWhere, stackA, stackB)); |
|
1192 } |
|
1193 }); |
|
1194 |
|
1195 if (result && !isWhere) { |
|
1196 // ensure both objects have the same number of properties |
|
1197 forIn(a, function(value, key, a) { |
|
1198 if (hasOwnProperty.call(a, key)) { |
|
1199 // `size` will be `-1` if `a` has more properties than `b` |
|
1200 return (result = --size > -1); |
|
1201 } |
|
1202 }); |
|
1203 } |
|
1204 } |
|
1205 stackA.pop(); |
|
1206 stackB.pop(); |
|
1207 |
|
1208 if (initedStack) { |
|
1209 releaseArray(stackA); |
|
1210 releaseArray(stackB); |
|
1211 } |
2961 } |
1212 return result; |
2962 return result; |
1213 } |
2963 } |
1214 |
2964 |
1215 /** |
2965 /** |
1216 * The base implementation of `_.merge` without argument juggling or support |
2966 * Creates a `_.countBy`, `_.groupBy`, `_.indexBy`, or `_.partition` function. |
1217 * for `thisArg` binding. |
2967 * |
1218 * |
2968 * @private |
1219 * @private |
2969 * @param {Function} setter The function to set keys and values of the accumulator object. |
1220 * @param {Object} object The destination object. |
2970 * @param {Function} [initializer] The function to initialize the accumulator object. |
1221 * @param {Object} source The source object. |
|
1222 * @param {Function} [callback] The function to customize merging properties. |
|
1223 * @param {Array} [stackA=[]] Tracks traversed source objects. |
|
1224 * @param {Array} [stackB=[]] Associates values with source counterparts. |
|
1225 */ |
|
1226 function baseMerge(object, source, callback, stackA, stackB) { |
|
1227 (isArray(source) ? forEach : forOwn)(source, function(source, key) { |
|
1228 var found, |
|
1229 isArr, |
|
1230 result = source, |
|
1231 value = object[key]; |
|
1232 |
|
1233 if (source && ((isArr = isArray(source)) || isPlainObject(source))) { |
|
1234 // avoid merging previously merged cyclic sources |
|
1235 var stackLength = stackA.length; |
|
1236 while (stackLength--) { |
|
1237 if ((found = stackA[stackLength] == source)) { |
|
1238 value = stackB[stackLength]; |
|
1239 break; |
|
1240 } |
|
1241 } |
|
1242 if (!found) { |
|
1243 var isShallow; |
|
1244 if (callback) { |
|
1245 result = callback(value, source); |
|
1246 if ((isShallow = typeof result != 'undefined')) { |
|
1247 value = result; |
|
1248 } |
|
1249 } |
|
1250 if (!isShallow) { |
|
1251 value = isArr |
|
1252 ? (isArray(value) ? value : []) |
|
1253 : (isPlainObject(value) ? value : {}); |
|
1254 } |
|
1255 // add `source` and associated `value` to the stack of traversed objects |
|
1256 stackA.push(source); |
|
1257 stackB.push(value); |
|
1258 |
|
1259 // recursively merge objects and arrays (susceptible to call stack limits) |
|
1260 if (!isShallow) { |
|
1261 baseMerge(value, source, callback, stackA, stackB); |
|
1262 } |
|
1263 } |
|
1264 } |
|
1265 else { |
|
1266 if (callback) { |
|
1267 result = callback(value, source); |
|
1268 if (typeof result == 'undefined') { |
|
1269 result = source; |
|
1270 } |
|
1271 } |
|
1272 if (typeof result != 'undefined') { |
|
1273 value = result; |
|
1274 } |
|
1275 } |
|
1276 object[key] = value; |
|
1277 }); |
|
1278 } |
|
1279 |
|
1280 /** |
|
1281 * The base implementation of `_.random` without argument juggling or support |
|
1282 * for returning floating-point numbers. |
|
1283 * |
|
1284 * @private |
|
1285 * @param {number} min The minimum possible value. |
|
1286 * @param {number} max The maximum possible value. |
|
1287 * @returns {number} Returns a random number. |
|
1288 */ |
|
1289 function baseRandom(min, max) { |
|
1290 return min + floor(nativeRandom() * (max - min + 1)); |
|
1291 } |
|
1292 |
|
1293 /** |
|
1294 * The base implementation of `_.uniq` without support for callback shorthands |
|
1295 * or `thisArg` binding. |
|
1296 * |
|
1297 * @private |
|
1298 * @param {Array} array The array to process. |
|
1299 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. |
|
1300 * @param {Function} [callback] The function called per iteration. |
|
1301 * @returns {Array} Returns a duplicate-value-free array. |
|
1302 */ |
|
1303 function baseUniq(array, isSorted, callback) { |
|
1304 var index = -1, |
|
1305 indexOf = getIndexOf(), |
|
1306 length = array ? array.length : 0, |
|
1307 result = []; |
|
1308 |
|
1309 var isLarge = !isSorted && length >= largeArraySize && indexOf === baseIndexOf, |
|
1310 seen = (callback || isLarge) ? getArray() : result; |
|
1311 |
|
1312 if (isLarge) { |
|
1313 var cache = createCache(seen); |
|
1314 indexOf = cacheIndexOf; |
|
1315 seen = cache; |
|
1316 } |
|
1317 while (++index < length) { |
|
1318 var value = array[index], |
|
1319 computed = callback ? callback(value, index, array) : value; |
|
1320 |
|
1321 if (isSorted |
|
1322 ? !index || seen[seen.length - 1] !== computed |
|
1323 : indexOf(seen, computed) < 0 |
|
1324 ) { |
|
1325 if (callback || isLarge) { |
|
1326 seen.push(computed); |
|
1327 } |
|
1328 result.push(value); |
|
1329 } |
|
1330 } |
|
1331 if (isLarge) { |
|
1332 releaseArray(seen.array); |
|
1333 releaseObject(seen); |
|
1334 } else if (callback) { |
|
1335 releaseArray(seen); |
|
1336 } |
|
1337 return result; |
|
1338 } |
|
1339 |
|
1340 /** |
|
1341 * Creates a function that aggregates a collection, creating an object composed |
|
1342 * of keys generated from the results of running each element of the collection |
|
1343 * through a callback. The given `setter` function sets the keys and values |
|
1344 * of the composed object. |
|
1345 * |
|
1346 * @private |
|
1347 * @param {Function} setter The setter function. |
|
1348 * @returns {Function} Returns the new aggregator function. |
2971 * @returns {Function} Returns the new aggregator function. |
1349 */ |
2972 */ |
1350 function createAggregator(setter) { |
2973 function createAggregator(setter, initializer) { |
1351 return function(collection, callback, thisArg) { |
2974 return function(collection, iteratee, thisArg) { |
1352 var result = {}; |
2975 var result = initializer ? initializer() : {}; |
1353 callback = lodash.createCallback(callback, thisArg, 3); |
2976 iteratee = getCallback(iteratee, thisArg, 3); |
1354 |
2977 |
1355 var index = -1, |
2978 if (isArray(collection)) { |
1356 length = collection ? collection.length : 0; |
2979 var index = -1, |
1357 |
2980 length = collection.length; |
1358 if (typeof length == 'number') { |
2981 |
1359 while (++index < length) { |
2982 while (++index < length) { |
1360 var value = collection[index]; |
2983 var value = collection[index]; |
1361 setter(result, value, callback(value, index, collection), collection); |
2984 setter(result, value, iteratee(value, index, collection), collection); |
1362 } |
2985 } |
1363 } else { |
2986 } else { |
1364 forOwn(collection, function(value, key, collection) { |
2987 baseEach(collection, function(value, key, collection) { |
1365 setter(result, value, callback(value, key, collection), collection); |
2988 setter(result, value, iteratee(value, key, collection), collection); |
1366 }); |
2989 }); |
1367 } |
2990 } |
1368 return result; |
2991 return result; |
1369 }; |
2992 }; |
1370 } |
2993 } |
1371 |
2994 |
1372 /** |
2995 /** |
1373 * Creates a function that, when called, either curries or invokes `func` |
2996 * Creates a `_.assign`, `_.defaults`, or `_.merge` function. |
1374 * with an optional `this` binding and partially applied arguments. |
2997 * |
|
2998 * @private |
|
2999 * @param {Function} assigner The function to assign values. |
|
3000 * @returns {Function} Returns the new assigner function. |
|
3001 */ |
|
3002 function createAssigner(assigner) { |
|
3003 return restParam(function(object, sources) { |
|
3004 var index = -1, |
|
3005 length = object == null ? 0 : sources.length, |
|
3006 customizer = length > 2 ? sources[length - 2] : undefined, |
|
3007 guard = length > 2 ? sources[2] : undefined, |
|
3008 thisArg = length > 1 ? sources[length - 1] : undefined; |
|
3009 |
|
3010 if (typeof customizer == 'function') { |
|
3011 customizer = bindCallback(customizer, thisArg, 5); |
|
3012 length -= 2; |
|
3013 } else { |
|
3014 customizer = typeof thisArg == 'function' ? thisArg : undefined; |
|
3015 length -= (customizer ? 1 : 0); |
|
3016 } |
|
3017 if (guard && isIterateeCall(sources[0], sources[1], guard)) { |
|
3018 customizer = length < 3 ? undefined : customizer; |
|
3019 length = 1; |
|
3020 } |
|
3021 while (++index < length) { |
|
3022 var source = sources[index]; |
|
3023 if (source) { |
|
3024 assigner(object, source, customizer); |
|
3025 } |
|
3026 } |
|
3027 return object; |
|
3028 }); |
|
3029 } |
|
3030 |
|
3031 /** |
|
3032 * Creates a `baseEach` or `baseEachRight` function. |
|
3033 * |
|
3034 * @private |
|
3035 * @param {Function} eachFunc The function to iterate over a collection. |
|
3036 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
3037 * @returns {Function} Returns the new base function. |
|
3038 */ |
|
3039 function createBaseEach(eachFunc, fromRight) { |
|
3040 return function(collection, iteratee) { |
|
3041 var length = collection ? getLength(collection) : 0; |
|
3042 if (!isLength(length)) { |
|
3043 return eachFunc(collection, iteratee); |
|
3044 } |
|
3045 var index = fromRight ? length : -1, |
|
3046 iterable = toObject(collection); |
|
3047 |
|
3048 while ((fromRight ? index-- : ++index < length)) { |
|
3049 if (iteratee(iterable[index], index, iterable) === false) { |
|
3050 break; |
|
3051 } |
|
3052 } |
|
3053 return collection; |
|
3054 }; |
|
3055 } |
|
3056 |
|
3057 /** |
|
3058 * Creates a base function for `_.forIn` or `_.forInRight`. |
|
3059 * |
|
3060 * @private |
|
3061 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
3062 * @returns {Function} Returns the new base function. |
|
3063 */ |
|
3064 function createBaseFor(fromRight) { |
|
3065 return function(object, iteratee, keysFunc) { |
|
3066 var iterable = toObject(object), |
|
3067 props = keysFunc(object), |
|
3068 length = props.length, |
|
3069 index = fromRight ? length : -1; |
|
3070 |
|
3071 while ((fromRight ? index-- : ++index < length)) { |
|
3072 var key = props[index]; |
|
3073 if (iteratee(iterable[key], key, iterable) === false) { |
|
3074 break; |
|
3075 } |
|
3076 } |
|
3077 return object; |
|
3078 }; |
|
3079 } |
|
3080 |
|
3081 /** |
|
3082 * Creates a function that wraps `func` and invokes it with the `this` |
|
3083 * binding of `thisArg`. |
|
3084 * |
|
3085 * @private |
|
3086 * @param {Function} func The function to bind. |
|
3087 * @param {*} [thisArg] The `this` binding of `func`. |
|
3088 * @returns {Function} Returns the new bound function. |
|
3089 */ |
|
3090 function createBindWrapper(func, thisArg) { |
|
3091 var Ctor = createCtorWrapper(func); |
|
3092 |
|
3093 function wrapper() { |
|
3094 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; |
|
3095 return fn.apply(thisArg, arguments); |
|
3096 } |
|
3097 return wrapper; |
|
3098 } |
|
3099 |
|
3100 /** |
|
3101 * Creates a `Set` cache object to optimize linear searches of large arrays. |
|
3102 * |
|
3103 * @private |
|
3104 * @param {Array} [values] The values to cache. |
|
3105 * @returns {null|Object} Returns the new cache object if `Set` is supported, else `null`. |
|
3106 */ |
|
3107 function createCache(values) { |
|
3108 return (nativeCreate && Set) ? new SetCache(values) : null; |
|
3109 } |
|
3110 |
|
3111 /** |
|
3112 * Creates a function that produces compound words out of the words in a |
|
3113 * given string. |
|
3114 * |
|
3115 * @private |
|
3116 * @param {Function} callback The function to combine each word. |
|
3117 * @returns {Function} Returns the new compounder function. |
|
3118 */ |
|
3119 function createCompounder(callback) { |
|
3120 return function(string) { |
|
3121 var index = -1, |
|
3122 array = words(deburr(string)), |
|
3123 length = array.length, |
|
3124 result = ''; |
|
3125 |
|
3126 while (++index < length) { |
|
3127 result = callback(result, array[index], index); |
|
3128 } |
|
3129 return result; |
|
3130 }; |
|
3131 } |
|
3132 |
|
3133 /** |
|
3134 * Creates a function that produces an instance of `Ctor` regardless of |
|
3135 * whether it was invoked as part of a `new` expression or by `call` or `apply`. |
|
3136 * |
|
3137 * @private |
|
3138 * @param {Function} Ctor The constructor to wrap. |
|
3139 * @returns {Function} Returns the new wrapped function. |
|
3140 */ |
|
3141 function createCtorWrapper(Ctor) { |
|
3142 return function() { |
|
3143 // Use a `switch` statement to work with class constructors. |
|
3144 // See http://ecma-international.org/ecma-262/6.0/#sec-ecmascript-function-objects-call-thisargument-argumentslist |
|
3145 // for more details. |
|
3146 var args = arguments; |
|
3147 switch (args.length) { |
|
3148 case 0: return new Ctor; |
|
3149 case 1: return new Ctor(args[0]); |
|
3150 case 2: return new Ctor(args[0], args[1]); |
|
3151 case 3: return new Ctor(args[0], args[1], args[2]); |
|
3152 case 4: return new Ctor(args[0], args[1], args[2], args[3]); |
|
3153 case 5: return new Ctor(args[0], args[1], args[2], args[3], args[4]); |
|
3154 case 6: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5]); |
|
3155 case 7: return new Ctor(args[0], args[1], args[2], args[3], args[4], args[5], args[6]); |
|
3156 } |
|
3157 var thisBinding = baseCreate(Ctor.prototype), |
|
3158 result = Ctor.apply(thisBinding, args); |
|
3159 |
|
3160 // Mimic the constructor's `return` behavior. |
|
3161 // See https://es5.github.io/#x13.2.2 for more details. |
|
3162 return isObject(result) ? result : thisBinding; |
|
3163 }; |
|
3164 } |
|
3165 |
|
3166 /** |
|
3167 * Creates a `_.curry` or `_.curryRight` function. |
|
3168 * |
|
3169 * @private |
|
3170 * @param {boolean} flag The curry bit flag. |
|
3171 * @returns {Function} Returns the new curry function. |
|
3172 */ |
|
3173 function createCurry(flag) { |
|
3174 function curryFunc(func, arity, guard) { |
|
3175 if (guard && isIterateeCall(func, arity, guard)) { |
|
3176 arity = undefined; |
|
3177 } |
|
3178 var result = createWrapper(func, flag, undefined, undefined, undefined, undefined, undefined, arity); |
|
3179 result.placeholder = curryFunc.placeholder; |
|
3180 return result; |
|
3181 } |
|
3182 return curryFunc; |
|
3183 } |
|
3184 |
|
3185 /** |
|
3186 * Creates a `_.defaults` or `_.defaultsDeep` function. |
|
3187 * |
|
3188 * @private |
|
3189 * @param {Function} assigner The function to assign values. |
|
3190 * @param {Function} customizer The function to customize assigned values. |
|
3191 * @returns {Function} Returns the new defaults function. |
|
3192 */ |
|
3193 function createDefaults(assigner, customizer) { |
|
3194 return restParam(function(args) { |
|
3195 var object = args[0]; |
|
3196 if (object == null) { |
|
3197 return object; |
|
3198 } |
|
3199 args.push(customizer); |
|
3200 return assigner.apply(undefined, args); |
|
3201 }); |
|
3202 } |
|
3203 |
|
3204 /** |
|
3205 * Creates a `_.max` or `_.min` function. |
|
3206 * |
|
3207 * @private |
|
3208 * @param {Function} comparator The function used to compare values. |
|
3209 * @param {*} exValue The initial extremum value. |
|
3210 * @returns {Function} Returns the new extremum function. |
|
3211 */ |
|
3212 function createExtremum(comparator, exValue) { |
|
3213 return function(collection, iteratee, thisArg) { |
|
3214 if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
|
3215 iteratee = undefined; |
|
3216 } |
|
3217 iteratee = getCallback(iteratee, thisArg, 3); |
|
3218 if (iteratee.length == 1) { |
|
3219 collection = isArray(collection) ? collection : toIterable(collection); |
|
3220 var result = arrayExtremum(collection, iteratee, comparator, exValue); |
|
3221 if (!(collection.length && result === exValue)) { |
|
3222 return result; |
|
3223 } |
|
3224 } |
|
3225 return baseExtremum(collection, iteratee, comparator, exValue); |
|
3226 }; |
|
3227 } |
|
3228 |
|
3229 /** |
|
3230 * Creates a `_.find` or `_.findLast` function. |
|
3231 * |
|
3232 * @private |
|
3233 * @param {Function} eachFunc The function to iterate over a collection. |
|
3234 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
3235 * @returns {Function} Returns the new find function. |
|
3236 */ |
|
3237 function createFind(eachFunc, fromRight) { |
|
3238 return function(collection, predicate, thisArg) { |
|
3239 predicate = getCallback(predicate, thisArg, 3); |
|
3240 if (isArray(collection)) { |
|
3241 var index = baseFindIndex(collection, predicate, fromRight); |
|
3242 return index > -1 ? collection[index] : undefined; |
|
3243 } |
|
3244 return baseFind(collection, predicate, eachFunc); |
|
3245 }; |
|
3246 } |
|
3247 |
|
3248 /** |
|
3249 * Creates a `_.findIndex` or `_.findLastIndex` function. |
|
3250 * |
|
3251 * @private |
|
3252 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
3253 * @returns {Function} Returns the new find function. |
|
3254 */ |
|
3255 function createFindIndex(fromRight) { |
|
3256 return function(array, predicate, thisArg) { |
|
3257 if (!(array && array.length)) { |
|
3258 return -1; |
|
3259 } |
|
3260 predicate = getCallback(predicate, thisArg, 3); |
|
3261 return baseFindIndex(array, predicate, fromRight); |
|
3262 }; |
|
3263 } |
|
3264 |
|
3265 /** |
|
3266 * Creates a `_.findKey` or `_.findLastKey` function. |
|
3267 * |
|
3268 * @private |
|
3269 * @param {Function} objectFunc The function to iterate over an object. |
|
3270 * @returns {Function} Returns the new find function. |
|
3271 */ |
|
3272 function createFindKey(objectFunc) { |
|
3273 return function(object, predicate, thisArg) { |
|
3274 predicate = getCallback(predicate, thisArg, 3); |
|
3275 return baseFind(object, predicate, objectFunc, true); |
|
3276 }; |
|
3277 } |
|
3278 |
|
3279 /** |
|
3280 * Creates a `_.flow` or `_.flowRight` function. |
|
3281 * |
|
3282 * @private |
|
3283 * @param {boolean} [fromRight] Specify iterating from right to left. |
|
3284 * @returns {Function} Returns the new flow function. |
|
3285 */ |
|
3286 function createFlow(fromRight) { |
|
3287 return function() { |
|
3288 var wrapper, |
|
3289 length = arguments.length, |
|
3290 index = fromRight ? length : -1, |
|
3291 leftIndex = 0, |
|
3292 funcs = Array(length); |
|
3293 |
|
3294 while ((fromRight ? index-- : ++index < length)) { |
|
3295 var func = funcs[leftIndex++] = arguments[index]; |
|
3296 if (typeof func != 'function') { |
|
3297 throw new TypeError(FUNC_ERROR_TEXT); |
|
3298 } |
|
3299 if (!wrapper && LodashWrapper.prototype.thru && getFuncName(func) == 'wrapper') { |
|
3300 wrapper = new LodashWrapper([], true); |
|
3301 } |
|
3302 } |
|
3303 index = wrapper ? -1 : length; |
|
3304 while (++index < length) { |
|
3305 func = funcs[index]; |
|
3306 |
|
3307 var funcName = getFuncName(func), |
|
3308 data = funcName == 'wrapper' ? getData(func) : undefined; |
|
3309 |
|
3310 if (data && isLaziable(data[0]) && data[1] == (ARY_FLAG | CURRY_FLAG | PARTIAL_FLAG | REARG_FLAG) && !data[4].length && data[9] == 1) { |
|
3311 wrapper = wrapper[getFuncName(data[0])].apply(wrapper, data[3]); |
|
3312 } else { |
|
3313 wrapper = (func.length == 1 && isLaziable(func)) ? wrapper[funcName]() : wrapper.thru(func); |
|
3314 } |
|
3315 } |
|
3316 return function() { |
|
3317 var args = arguments, |
|
3318 value = args[0]; |
|
3319 |
|
3320 if (wrapper && args.length == 1 && isArray(value) && value.length >= LARGE_ARRAY_SIZE) { |
|
3321 return wrapper.plant(value).value(); |
|
3322 } |
|
3323 var index = 0, |
|
3324 result = length ? funcs[index].apply(this, args) : value; |
|
3325 |
|
3326 while (++index < length) { |
|
3327 result = funcs[index].call(this, result); |
|
3328 } |
|
3329 return result; |
|
3330 }; |
|
3331 }; |
|
3332 } |
|
3333 |
|
3334 /** |
|
3335 * Creates a function for `_.forEach` or `_.forEachRight`. |
|
3336 * |
|
3337 * @private |
|
3338 * @param {Function} arrayFunc The function to iterate over an array. |
|
3339 * @param {Function} eachFunc The function to iterate over a collection. |
|
3340 * @returns {Function} Returns the new each function. |
|
3341 */ |
|
3342 function createForEach(arrayFunc, eachFunc) { |
|
3343 return function(collection, iteratee, thisArg) { |
|
3344 return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
|
3345 ? arrayFunc(collection, iteratee) |
|
3346 : eachFunc(collection, bindCallback(iteratee, thisArg, 3)); |
|
3347 }; |
|
3348 } |
|
3349 |
|
3350 /** |
|
3351 * Creates a function for `_.forIn` or `_.forInRight`. |
|
3352 * |
|
3353 * @private |
|
3354 * @param {Function} objectFunc The function to iterate over an object. |
|
3355 * @returns {Function} Returns the new each function. |
|
3356 */ |
|
3357 function createForIn(objectFunc) { |
|
3358 return function(object, iteratee, thisArg) { |
|
3359 if (typeof iteratee != 'function' || thisArg !== undefined) { |
|
3360 iteratee = bindCallback(iteratee, thisArg, 3); |
|
3361 } |
|
3362 return objectFunc(object, iteratee, keysIn); |
|
3363 }; |
|
3364 } |
|
3365 |
|
3366 /** |
|
3367 * Creates a function for `_.forOwn` or `_.forOwnRight`. |
|
3368 * |
|
3369 * @private |
|
3370 * @param {Function} objectFunc The function to iterate over an object. |
|
3371 * @returns {Function} Returns the new each function. |
|
3372 */ |
|
3373 function createForOwn(objectFunc) { |
|
3374 return function(object, iteratee, thisArg) { |
|
3375 if (typeof iteratee != 'function' || thisArg !== undefined) { |
|
3376 iteratee = bindCallback(iteratee, thisArg, 3); |
|
3377 } |
|
3378 return objectFunc(object, iteratee); |
|
3379 }; |
|
3380 } |
|
3381 |
|
3382 /** |
|
3383 * Creates a function for `_.mapKeys` or `_.mapValues`. |
|
3384 * |
|
3385 * @private |
|
3386 * @param {boolean} [isMapKeys] Specify mapping keys instead of values. |
|
3387 * @returns {Function} Returns the new map function. |
|
3388 */ |
|
3389 function createObjectMapper(isMapKeys) { |
|
3390 return function(object, iteratee, thisArg) { |
|
3391 var result = {}; |
|
3392 iteratee = getCallback(iteratee, thisArg, 3); |
|
3393 |
|
3394 baseForOwn(object, function(value, key, object) { |
|
3395 var mapped = iteratee(value, key, object); |
|
3396 key = isMapKeys ? mapped : key; |
|
3397 value = isMapKeys ? value : mapped; |
|
3398 result[key] = value; |
|
3399 }); |
|
3400 return result; |
|
3401 }; |
|
3402 } |
|
3403 |
|
3404 /** |
|
3405 * Creates a function for `_.padLeft` or `_.padRight`. |
|
3406 * |
|
3407 * @private |
|
3408 * @param {boolean} [fromRight] Specify padding from the right. |
|
3409 * @returns {Function} Returns the new pad function. |
|
3410 */ |
|
3411 function createPadDir(fromRight) { |
|
3412 return function(string, length, chars) { |
|
3413 string = baseToString(string); |
|
3414 return (fromRight ? string : '') + createPadding(string, length, chars) + (fromRight ? '' : string); |
|
3415 }; |
|
3416 } |
|
3417 |
|
3418 /** |
|
3419 * Creates a `_.partial` or `_.partialRight` function. |
|
3420 * |
|
3421 * @private |
|
3422 * @param {boolean} flag The partial bit flag. |
|
3423 * @returns {Function} Returns the new partial function. |
|
3424 */ |
|
3425 function createPartial(flag) { |
|
3426 var partialFunc = restParam(function(func, partials) { |
|
3427 var holders = replaceHolders(partials, partialFunc.placeholder); |
|
3428 return createWrapper(func, flag, undefined, partials, holders); |
|
3429 }); |
|
3430 return partialFunc; |
|
3431 } |
|
3432 |
|
3433 /** |
|
3434 * Creates a function for `_.reduce` or `_.reduceRight`. |
|
3435 * |
|
3436 * @private |
|
3437 * @param {Function} arrayFunc The function to iterate over an array. |
|
3438 * @param {Function} eachFunc The function to iterate over a collection. |
|
3439 * @returns {Function} Returns the new each function. |
|
3440 */ |
|
3441 function createReduce(arrayFunc, eachFunc) { |
|
3442 return function(collection, iteratee, accumulator, thisArg) { |
|
3443 var initFromArray = arguments.length < 3; |
|
3444 return (typeof iteratee == 'function' && thisArg === undefined && isArray(collection)) |
|
3445 ? arrayFunc(collection, iteratee, accumulator, initFromArray) |
|
3446 : baseReduce(collection, getCallback(iteratee, thisArg, 4), accumulator, initFromArray, eachFunc); |
|
3447 }; |
|
3448 } |
|
3449 |
|
3450 /** |
|
3451 * Creates a function that wraps `func` and invokes it with optional `this` |
|
3452 * binding of, partial application, and currying. |
1375 * |
3453 * |
1376 * @private |
3454 * @private |
1377 * @param {Function|string} func The function or method name to reference. |
3455 * @param {Function|string} func The function or method name to reference. |
1378 * @param {number} bitmask The bitmask of method flags to compose. |
3456 * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
|
3457 * @param {*} [thisArg] The `this` binding of `func`. |
|
3458 * @param {Array} [partials] The arguments to prepend to those provided to the new function. |
|
3459 * @param {Array} [holders] The `partials` placeholder indexes. |
|
3460 * @param {Array} [partialsRight] The arguments to append to those provided to the new function. |
|
3461 * @param {Array} [holdersRight] The `partialsRight` placeholder indexes. |
|
3462 * @param {Array} [argPos] The argument positions of the new function. |
|
3463 * @param {number} [ary] The arity cap of `func`. |
|
3464 * @param {number} [arity] The arity of `func`. |
|
3465 * @returns {Function} Returns the new wrapped function. |
|
3466 */ |
|
3467 function createHybridWrapper(func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity) { |
|
3468 var isAry = bitmask & ARY_FLAG, |
|
3469 isBind = bitmask & BIND_FLAG, |
|
3470 isBindKey = bitmask & BIND_KEY_FLAG, |
|
3471 isCurry = bitmask & CURRY_FLAG, |
|
3472 isCurryBound = bitmask & CURRY_BOUND_FLAG, |
|
3473 isCurryRight = bitmask & CURRY_RIGHT_FLAG, |
|
3474 Ctor = isBindKey ? undefined : createCtorWrapper(func); |
|
3475 |
|
3476 function wrapper() { |
|
3477 // Avoid `arguments` object use disqualifying optimizations by |
|
3478 // converting it to an array before providing it to other functions. |
|
3479 var length = arguments.length, |
|
3480 index = length, |
|
3481 args = Array(length); |
|
3482 |
|
3483 while (index--) { |
|
3484 args[index] = arguments[index]; |
|
3485 } |
|
3486 if (partials) { |
|
3487 args = composeArgs(args, partials, holders); |
|
3488 } |
|
3489 if (partialsRight) { |
|
3490 args = composeArgsRight(args, partialsRight, holdersRight); |
|
3491 } |
|
3492 if (isCurry || isCurryRight) { |
|
3493 var placeholder = wrapper.placeholder, |
|
3494 argsHolders = replaceHolders(args, placeholder); |
|
3495 |
|
3496 length -= argsHolders.length; |
|
3497 if (length < arity) { |
|
3498 var newArgPos = argPos ? arrayCopy(argPos) : undefined, |
|
3499 newArity = nativeMax(arity - length, 0), |
|
3500 newsHolders = isCurry ? argsHolders : undefined, |
|
3501 newHoldersRight = isCurry ? undefined : argsHolders, |
|
3502 newPartials = isCurry ? args : undefined, |
|
3503 newPartialsRight = isCurry ? undefined : args; |
|
3504 |
|
3505 bitmask |= (isCurry ? PARTIAL_FLAG : PARTIAL_RIGHT_FLAG); |
|
3506 bitmask &= ~(isCurry ? PARTIAL_RIGHT_FLAG : PARTIAL_FLAG); |
|
3507 |
|
3508 if (!isCurryBound) { |
|
3509 bitmask &= ~(BIND_FLAG | BIND_KEY_FLAG); |
|
3510 } |
|
3511 var newData = [func, bitmask, thisArg, newPartials, newsHolders, newPartialsRight, newHoldersRight, newArgPos, ary, newArity], |
|
3512 result = createHybridWrapper.apply(undefined, newData); |
|
3513 |
|
3514 if (isLaziable(func)) { |
|
3515 setData(result, newData); |
|
3516 } |
|
3517 result.placeholder = placeholder; |
|
3518 return result; |
|
3519 } |
|
3520 } |
|
3521 var thisBinding = isBind ? thisArg : this, |
|
3522 fn = isBindKey ? thisBinding[func] : func; |
|
3523 |
|
3524 if (argPos) { |
|
3525 args = reorder(args, argPos); |
|
3526 } |
|
3527 if (isAry && ary < args.length) { |
|
3528 args.length = ary; |
|
3529 } |
|
3530 if (this && this !== root && this instanceof wrapper) { |
|
3531 fn = Ctor || createCtorWrapper(func); |
|
3532 } |
|
3533 return fn.apply(thisBinding, args); |
|
3534 } |
|
3535 return wrapper; |
|
3536 } |
|
3537 |
|
3538 /** |
|
3539 * Creates the padding required for `string` based on the given `length`. |
|
3540 * The `chars` string is truncated if the number of characters exceeds `length`. |
|
3541 * |
|
3542 * @private |
|
3543 * @param {string} string The string to create padding for. |
|
3544 * @param {number} [length=0] The padding length. |
|
3545 * @param {string} [chars=' '] The string used as padding. |
|
3546 * @returns {string} Returns the pad for `string`. |
|
3547 */ |
|
3548 function createPadding(string, length, chars) { |
|
3549 var strLength = string.length; |
|
3550 length = +length; |
|
3551 |
|
3552 if (strLength >= length || !nativeIsFinite(length)) { |
|
3553 return ''; |
|
3554 } |
|
3555 var padLength = length - strLength; |
|
3556 chars = chars == null ? ' ' : (chars + ''); |
|
3557 return repeat(chars, nativeCeil(padLength / chars.length)).slice(0, padLength); |
|
3558 } |
|
3559 |
|
3560 /** |
|
3561 * Creates a function that wraps `func` and invokes it with the optional `this` |
|
3562 * binding of `thisArg` and the `partials` prepended to those provided to |
|
3563 * the wrapper. |
|
3564 * |
|
3565 * @private |
|
3566 * @param {Function} func The function to partially apply arguments to. |
|
3567 * @param {number} bitmask The bitmask of flags. See `createWrapper` for more details. |
|
3568 * @param {*} thisArg The `this` binding of `func`. |
|
3569 * @param {Array} partials The arguments to prepend to those provided to the new function. |
|
3570 * @returns {Function} Returns the new bound function. |
|
3571 */ |
|
3572 function createPartialWrapper(func, bitmask, thisArg, partials) { |
|
3573 var isBind = bitmask & BIND_FLAG, |
|
3574 Ctor = createCtorWrapper(func); |
|
3575 |
|
3576 function wrapper() { |
|
3577 // Avoid `arguments` object use disqualifying optimizations by |
|
3578 // converting it to an array before providing it `func`. |
|
3579 var argsIndex = -1, |
|
3580 argsLength = arguments.length, |
|
3581 leftIndex = -1, |
|
3582 leftLength = partials.length, |
|
3583 args = Array(leftLength + argsLength); |
|
3584 |
|
3585 while (++leftIndex < leftLength) { |
|
3586 args[leftIndex] = partials[leftIndex]; |
|
3587 } |
|
3588 while (argsLength--) { |
|
3589 args[leftIndex++] = arguments[++argsIndex]; |
|
3590 } |
|
3591 var fn = (this && this !== root && this instanceof wrapper) ? Ctor : func; |
|
3592 return fn.apply(isBind ? thisArg : this, args); |
|
3593 } |
|
3594 return wrapper; |
|
3595 } |
|
3596 |
|
3597 /** |
|
3598 * Creates a `_.ceil`, `_.floor`, or `_.round` function. |
|
3599 * |
|
3600 * @private |
|
3601 * @param {string} methodName The name of the `Math` method to use when rounding. |
|
3602 * @returns {Function} Returns the new round function. |
|
3603 */ |
|
3604 function createRound(methodName) { |
|
3605 var func = Math[methodName]; |
|
3606 return function(number, precision) { |
|
3607 precision = precision === undefined ? 0 : (+precision || 0); |
|
3608 if (precision) { |
|
3609 precision = pow(10, precision); |
|
3610 return func(number * precision) / precision; |
|
3611 } |
|
3612 return func(number); |
|
3613 }; |
|
3614 } |
|
3615 |
|
3616 /** |
|
3617 * Creates a `_.sortedIndex` or `_.sortedLastIndex` function. |
|
3618 * |
|
3619 * @private |
|
3620 * @param {boolean} [retHighest] Specify returning the highest qualified index. |
|
3621 * @returns {Function} Returns the new index function. |
|
3622 */ |
|
3623 function createSortedIndex(retHighest) { |
|
3624 return function(array, value, iteratee, thisArg) { |
|
3625 var callback = getCallback(iteratee); |
|
3626 return (iteratee == null && callback === baseCallback) |
|
3627 ? binaryIndex(array, value, retHighest) |
|
3628 : binaryIndexBy(array, value, callback(iteratee, thisArg, 1), retHighest); |
|
3629 }; |
|
3630 } |
|
3631 |
|
3632 /** |
|
3633 * Creates a function that either curries or invokes `func` with optional |
|
3634 * `this` binding and partially applied arguments. |
|
3635 * |
|
3636 * @private |
|
3637 * @param {Function|string} func The function or method name to reference. |
|
3638 * @param {number} bitmask The bitmask of flags. |
1379 * The bitmask may be composed of the following flags: |
3639 * The bitmask may be composed of the following flags: |
1380 * 1 - `_.bind` |
3640 * 1 - `_.bind` |
1381 * 2 - `_.bindKey` |
3641 * 2 - `_.bindKey` |
1382 * 4 - `_.curry` |
3642 * 4 - `_.curry` or `_.curryRight` of a bound function |
1383 * 8 - `_.curry` (bound) |
3643 * 8 - `_.curry` |
1384 * 16 - `_.partial` |
3644 * 16 - `_.curryRight` |
1385 * 32 - `_.partialRight` |
3645 * 32 - `_.partial` |
1386 * @param {Array} [partialArgs] An array of arguments to prepend to those |
3646 * 64 - `_.partialRight` |
1387 * provided to the new function. |
3647 * 128 - `_.rearg` |
1388 * @param {Array} [partialRightArgs] An array of arguments to append to those |
3648 * 256 - `_.ary` |
1389 * provided to the new function. |
|
1390 * @param {*} [thisArg] The `this` binding of `func`. |
3649 * @param {*} [thisArg] The `this` binding of `func`. |
|
3650 * @param {Array} [partials] The arguments to be partially applied. |
|
3651 * @param {Array} [holders] The `partials` placeholder indexes. |
|
3652 * @param {Array} [argPos] The argument positions of the new function. |
|
3653 * @param {number} [ary] The arity cap of `func`. |
1391 * @param {number} [arity] The arity of `func`. |
3654 * @param {number} [arity] The arity of `func`. |
1392 * @returns {Function} Returns the new function. |
3655 * @returns {Function} Returns the new wrapped function. |
1393 */ |
3656 */ |
1394 function createWrapper(func, bitmask, partialArgs, partialRightArgs, thisArg, arity) { |
3657 function createWrapper(func, bitmask, thisArg, partials, holders, argPos, ary, arity) { |
1395 var isBind = bitmask & 1, |
3658 var isBindKey = bitmask & BIND_KEY_FLAG; |
1396 isBindKey = bitmask & 2, |
3659 if (!isBindKey && typeof func != 'function') { |
1397 isCurry = bitmask & 4, |
3660 throw new TypeError(FUNC_ERROR_TEXT); |
1398 isCurryBound = bitmask & 8, |
3661 } |
1399 isPartial = bitmask & 16, |
3662 var length = partials ? partials.length : 0; |
1400 isPartialRight = bitmask & 32; |
3663 if (!length) { |
1401 |
3664 bitmask &= ~(PARTIAL_FLAG | PARTIAL_RIGHT_FLAG); |
1402 if (!isBindKey && !isFunction(func)) { |
3665 partials = holders = undefined; |
1403 throw new TypeError; |
3666 } |
1404 } |
3667 length -= (holders ? holders.length : 0); |
1405 if (isPartial && !partialArgs.length) { |
3668 if (bitmask & PARTIAL_RIGHT_FLAG) { |
1406 bitmask &= ~16; |
3669 var partialsRight = partials, |
1407 isPartial = partialArgs = false; |
3670 holdersRight = holders; |
1408 } |
3671 |
1409 if (isPartialRight && !partialRightArgs.length) { |
3672 partials = holders = undefined; |
1410 bitmask &= ~32; |
3673 } |
1411 isPartialRight = partialRightArgs = false; |
3674 var data = isBindKey ? undefined : getData(func), |
1412 } |
3675 newData = [func, bitmask, thisArg, partials, holders, partialsRight, holdersRight, argPos, ary, arity]; |
1413 var bindData = func && func.__bindData__; |
3676 |
1414 if (bindData && bindData !== true) { |
3677 if (data) { |
1415 // clone `bindData` |
3678 mergeData(newData, data); |
1416 bindData = slice(bindData); |
3679 bitmask = newData[1]; |
1417 if (bindData[2]) { |
3680 arity = newData[9]; |
1418 bindData[2] = slice(bindData[2]); |
3681 } |
1419 } |
3682 newData[9] = arity == null |
1420 if (bindData[3]) { |
3683 ? (isBindKey ? 0 : func.length) |
1421 bindData[3] = slice(bindData[3]); |
3684 : (nativeMax(arity - length, 0) || 0); |
1422 } |
3685 |
1423 // set `thisBinding` is not previously bound |
3686 if (bitmask == BIND_FLAG) { |
1424 if (isBind && !(bindData[1] & 1)) { |
3687 var result = createBindWrapper(newData[0], newData[2]); |
1425 bindData[4] = thisArg; |
3688 } else if ((bitmask == PARTIAL_FLAG || bitmask == (BIND_FLAG | PARTIAL_FLAG)) && !newData[4].length) { |
1426 } |
3689 result = createPartialWrapper.apply(undefined, newData); |
1427 // set if previously bound but not currently (subsequent curried functions) |
3690 } else { |
1428 if (!isBind && bindData[1] & 1) { |
3691 result = createHybridWrapper.apply(undefined, newData); |
1429 bitmask |= 8; |
3692 } |
1430 } |
3693 var setter = data ? baseSetData : setData; |
1431 // set curried arity if not yet set |
3694 return setter(result, newData); |
1432 if (isCurry && !(bindData[1] & 4)) { |
3695 } |
1433 bindData[5] = arity; |
3696 |
1434 } |
3697 /** |
1435 // append partial left arguments |
3698 * A specialized version of `baseIsEqualDeep` for arrays with support for |
1436 if (isPartial) { |
3699 * partial deep comparisons. |
1437 push.apply(bindData[2] || (bindData[2] = []), partialArgs); |
3700 * |
1438 } |
3701 * @private |
1439 // append partial right arguments |
3702 * @param {Array} array The array to compare. |
1440 if (isPartialRight) { |
3703 * @param {Array} other The other array to compare. |
1441 unshift.apply(bindData[3] || (bindData[3] = []), partialRightArgs); |
3704 * @param {Function} equalFunc The function to determine equivalents of values. |
1442 } |
3705 * @param {Function} [customizer] The function to customize comparing arrays. |
1443 // merge flags |
3706 * @param {boolean} [isLoose] Specify performing partial comparisons. |
1444 bindData[1] |= bitmask; |
3707 * @param {Array} [stackA] Tracks traversed `value` objects. |
1445 return createWrapper.apply(null, bindData); |
3708 * @param {Array} [stackB] Tracks traversed `other` objects. |
1446 } |
3709 * @returns {boolean} Returns `true` if the arrays are equivalent, else `false`. |
1447 // fast path for `_.bind` |
3710 */ |
1448 var creater = (bitmask == 1 || bitmask === 17) ? baseBind : baseCreateWrapper; |
3711 function equalArrays(array, other, equalFunc, customizer, isLoose, stackA, stackB) { |
1449 return creater([func, bitmask, partialArgs, partialRightArgs, thisArg, arity]); |
3712 var index = -1, |
1450 } |
3713 arrLength = array.length, |
1451 |
3714 othLength = other.length; |
1452 /** |
3715 |
1453 * Used by `escape` to convert characters to HTML entities. |
3716 if (arrLength != othLength && !(isLoose && othLength > arrLength)) { |
1454 * |
3717 return false; |
1455 * @private |
3718 } |
1456 * @param {string} match The matched character to escape. |
3719 // Ignore non-index properties. |
1457 * @returns {string} Returns the escaped character. |
3720 while (++index < arrLength) { |
1458 */ |
3721 var arrValue = array[index], |
1459 function escapeHtmlChar(match) { |
3722 othValue = other[index], |
1460 return htmlEscapes[match]; |
3723 result = customizer ? customizer(isLoose ? othValue : arrValue, isLoose ? arrValue : othValue, index) : undefined; |
|
3724 |
|
3725 if (result !== undefined) { |
|
3726 if (result) { |
|
3727 continue; |
|
3728 } |
|
3729 return false; |
|
3730 } |
|
3731 // Recursively compare arrays (susceptible to call stack limits). |
|
3732 if (isLoose) { |
|
3733 if (!arraySome(other, function(othValue) { |
|
3734 return arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB); |
|
3735 })) { |
|
3736 return false; |
|
3737 } |
|
3738 } else if (!(arrValue === othValue || equalFunc(arrValue, othValue, customizer, isLoose, stackA, stackB))) { |
|
3739 return false; |
|
3740 } |
|
3741 } |
|
3742 return true; |
|
3743 } |
|
3744 |
|
3745 /** |
|
3746 * A specialized version of `baseIsEqualDeep` for comparing objects of |
|
3747 * the same `toStringTag`. |
|
3748 * |
|
3749 * **Note:** This function only supports comparing values with tags of |
|
3750 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
|
3751 * |
|
3752 * @private |
|
3753 * @param {Object} object The object to compare. |
|
3754 * @param {Object} other The other object to compare. |
|
3755 * @param {string} tag The `toStringTag` of the objects to compare. |
|
3756 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
3757 */ |
|
3758 function equalByTag(object, other, tag) { |
|
3759 switch (tag) { |
|
3760 case boolTag: |
|
3761 case dateTag: |
|
3762 // Coerce dates and booleans to numbers, dates to milliseconds and booleans |
|
3763 // to `1` or `0` treating invalid dates coerced to `NaN` as not equal. |
|
3764 return +object == +other; |
|
3765 |
|
3766 case errorTag: |
|
3767 return object.name == other.name && object.message == other.message; |
|
3768 |
|
3769 case numberTag: |
|
3770 // Treat `NaN` vs. `NaN` as equal. |
|
3771 return (object != +object) |
|
3772 ? other != +other |
|
3773 : object == +other; |
|
3774 |
|
3775 case regexpTag: |
|
3776 case stringTag: |
|
3777 // Coerce regexes to strings and treat strings primitives and string |
|
3778 // objects as equal. See https://es5.github.io/#x15.10.6.4 for more details. |
|
3779 return object == (other + ''); |
|
3780 } |
|
3781 return false; |
|
3782 } |
|
3783 |
|
3784 /** |
|
3785 * A specialized version of `baseIsEqualDeep` for objects with support for |
|
3786 * partial deep comparisons. |
|
3787 * |
|
3788 * @private |
|
3789 * @param {Object} object The object to compare. |
|
3790 * @param {Object} other The other object to compare. |
|
3791 * @param {Function} equalFunc The function to determine equivalents of values. |
|
3792 * @param {Function} [customizer] The function to customize comparing values. |
|
3793 * @param {boolean} [isLoose] Specify performing partial comparisons. |
|
3794 * @param {Array} [stackA] Tracks traversed `value` objects. |
|
3795 * @param {Array} [stackB] Tracks traversed `other` objects. |
|
3796 * @returns {boolean} Returns `true` if the objects are equivalent, else `false`. |
|
3797 */ |
|
3798 function equalObjects(object, other, equalFunc, customizer, isLoose, stackA, stackB) { |
|
3799 var objProps = keys(object), |
|
3800 objLength = objProps.length, |
|
3801 othProps = keys(other), |
|
3802 othLength = othProps.length; |
|
3803 |
|
3804 if (objLength != othLength && !isLoose) { |
|
3805 return false; |
|
3806 } |
|
3807 var index = objLength; |
|
3808 while (index--) { |
|
3809 var key = objProps[index]; |
|
3810 if (!(isLoose ? key in other : hasOwnProperty.call(other, key))) { |
|
3811 return false; |
|
3812 } |
|
3813 } |
|
3814 var skipCtor = isLoose; |
|
3815 while (++index < objLength) { |
|
3816 key = objProps[index]; |
|
3817 var objValue = object[key], |
|
3818 othValue = other[key], |
|
3819 result = customizer ? customizer(isLoose ? othValue : objValue, isLoose? objValue : othValue, key) : undefined; |
|
3820 |
|
3821 // Recursively compare objects (susceptible to call stack limits). |
|
3822 if (!(result === undefined ? equalFunc(objValue, othValue, customizer, isLoose, stackA, stackB) : result)) { |
|
3823 return false; |
|
3824 } |
|
3825 skipCtor || (skipCtor = key == 'constructor'); |
|
3826 } |
|
3827 if (!skipCtor) { |
|
3828 var objCtor = object.constructor, |
|
3829 othCtor = other.constructor; |
|
3830 |
|
3831 // Non `Object` object instances with different constructors are not equal. |
|
3832 if (objCtor != othCtor && |
|
3833 ('constructor' in object && 'constructor' in other) && |
|
3834 !(typeof objCtor == 'function' && objCtor instanceof objCtor && |
|
3835 typeof othCtor == 'function' && othCtor instanceof othCtor)) { |
|
3836 return false; |
|
3837 } |
|
3838 } |
|
3839 return true; |
|
3840 } |
|
3841 |
|
3842 /** |
|
3843 * Gets the appropriate "callback" function. If the `_.callback` method is |
|
3844 * customized this function returns the custom method, otherwise it returns |
|
3845 * the `baseCallback` function. If arguments are provided the chosen function |
|
3846 * is invoked with them and its result is returned. |
|
3847 * |
|
3848 * @private |
|
3849 * @returns {Function} Returns the chosen function or its result. |
|
3850 */ |
|
3851 function getCallback(func, thisArg, argCount) { |
|
3852 var result = lodash.callback || callback; |
|
3853 result = result === callback ? baseCallback : result; |
|
3854 return argCount ? result(func, thisArg, argCount) : result; |
|
3855 } |
|
3856 |
|
3857 /** |
|
3858 * Gets metadata for `func`. |
|
3859 * |
|
3860 * @private |
|
3861 * @param {Function} func The function to query. |
|
3862 * @returns {*} Returns the metadata for `func`. |
|
3863 */ |
|
3864 var getData = !metaMap ? noop : function(func) { |
|
3865 return metaMap.get(func); |
|
3866 }; |
|
3867 |
|
3868 /** |
|
3869 * Gets the name of `func`. |
|
3870 * |
|
3871 * @private |
|
3872 * @param {Function} func The function to query. |
|
3873 * @returns {string} Returns the function name. |
|
3874 */ |
|
3875 function getFuncName(func) { |
|
3876 var result = (func.name + ''), |
|
3877 array = realNames[result], |
|
3878 length = array ? array.length : 0; |
|
3879 |
|
3880 while (length--) { |
|
3881 var data = array[length], |
|
3882 otherFunc = data.func; |
|
3883 if (otherFunc == null || otherFunc == func) { |
|
3884 return data.name; |
|
3885 } |
|
3886 } |
|
3887 return result; |
1461 } |
3888 } |
1462 |
3889 |
1463 /** |
3890 /** |
1464 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is |
3891 * Gets the appropriate "indexOf" function. If the `_.indexOf` method is |
1465 * customized, this method returns the custom method, otherwise it returns |
3892 * customized this function returns the custom method, otherwise it returns |
1466 * the `baseIndexOf` function. |
3893 * the `baseIndexOf` function. If arguments are provided the chosen function |
1467 * |
3894 * is invoked with them and its result is returned. |
1468 * @private |
3895 * |
1469 * @returns {Function} Returns the "indexOf" function. |
3896 * @private |
1470 */ |
3897 * @returns {Function|number} Returns the chosen function or its result. |
1471 function getIndexOf() { |
3898 */ |
1472 var result = (result = lodash.indexOf) === indexOf ? baseIndexOf : result; |
3899 function getIndexOf(collection, target, fromIndex) { |
|
3900 var result = lodash.indexOf || indexOf; |
|
3901 result = result === indexOf ? baseIndexOf : result; |
|
3902 return collection ? result(collection, target, fromIndex) : result; |
|
3903 } |
|
3904 |
|
3905 /** |
|
3906 * Gets the "length" property value of `object`. |
|
3907 * |
|
3908 * **Note:** This function is used to avoid a [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) |
|
3909 * that affects Safari on at least iOS 8.1-8.3 ARM64. |
|
3910 * |
|
3911 * @private |
|
3912 * @param {Object} object The object to query. |
|
3913 * @returns {*} Returns the "length" value. |
|
3914 */ |
|
3915 var getLength = baseProperty('length'); |
|
3916 |
|
3917 /** |
|
3918 * Gets the propery names, values, and compare flags of `object`. |
|
3919 * |
|
3920 * @private |
|
3921 * @param {Object} object The object to query. |
|
3922 * @returns {Array} Returns the match data of `object`. |
|
3923 */ |
|
3924 function getMatchData(object) { |
|
3925 var result = pairs(object), |
|
3926 length = result.length; |
|
3927 |
|
3928 while (length--) { |
|
3929 result[length][2] = isStrictComparable(result[length][1]); |
|
3930 } |
1473 return result; |
3931 return result; |
1474 } |
3932 } |
1475 |
3933 |
1476 /** |
3934 /** |
1477 * Checks if `value` is a native function. |
3935 * Gets the native function at `key` of `object`. |
|
3936 * |
|
3937 * @private |
|
3938 * @param {Object} object The object to query. |
|
3939 * @param {string} key The key of the method to get. |
|
3940 * @returns {*} Returns the function if it's native, else `undefined`. |
|
3941 */ |
|
3942 function getNative(object, key) { |
|
3943 var value = object == null ? undefined : object[key]; |
|
3944 return isNative(value) ? value : undefined; |
|
3945 } |
|
3946 |
|
3947 /** |
|
3948 * Gets the view, applying any `transforms` to the `start` and `end` positions. |
|
3949 * |
|
3950 * @private |
|
3951 * @param {number} start The start of the view. |
|
3952 * @param {number} end The end of the view. |
|
3953 * @param {Array} transforms The transformations to apply to the view. |
|
3954 * @returns {Object} Returns an object containing the `start` and `end` |
|
3955 * positions of the view. |
|
3956 */ |
|
3957 function getView(start, end, transforms) { |
|
3958 var index = -1, |
|
3959 length = transforms.length; |
|
3960 |
|
3961 while (++index < length) { |
|
3962 var data = transforms[index], |
|
3963 size = data.size; |
|
3964 |
|
3965 switch (data.type) { |
|
3966 case 'drop': start += size; break; |
|
3967 case 'dropRight': end -= size; break; |
|
3968 case 'take': end = nativeMin(end, start + size); break; |
|
3969 case 'takeRight': start = nativeMax(start, end - size); break; |
|
3970 } |
|
3971 } |
|
3972 return { 'start': start, 'end': end }; |
|
3973 } |
|
3974 |
|
3975 /** |
|
3976 * Initializes an array clone. |
|
3977 * |
|
3978 * @private |
|
3979 * @param {Array} array The array to clone. |
|
3980 * @returns {Array} Returns the initialized clone. |
|
3981 */ |
|
3982 function initCloneArray(array) { |
|
3983 var length = array.length, |
|
3984 result = new array.constructor(length); |
|
3985 |
|
3986 // Add array properties assigned by `RegExp#exec`. |
|
3987 if (length && typeof array[0] == 'string' && hasOwnProperty.call(array, 'index')) { |
|
3988 result.index = array.index; |
|
3989 result.input = array.input; |
|
3990 } |
|
3991 return result; |
|
3992 } |
|
3993 |
|
3994 /** |
|
3995 * Initializes an object clone. |
|
3996 * |
|
3997 * @private |
|
3998 * @param {Object} object The object to clone. |
|
3999 * @returns {Object} Returns the initialized clone. |
|
4000 */ |
|
4001 function initCloneObject(object) { |
|
4002 var Ctor = object.constructor; |
|
4003 if (!(typeof Ctor == 'function' && Ctor instanceof Ctor)) { |
|
4004 Ctor = Object; |
|
4005 } |
|
4006 return new Ctor; |
|
4007 } |
|
4008 |
|
4009 /** |
|
4010 * Initializes an object clone based on its `toStringTag`. |
|
4011 * |
|
4012 * **Note:** This function only supports cloning values with tags of |
|
4013 * `Boolean`, `Date`, `Error`, `Number`, `RegExp`, or `String`. |
|
4014 * |
|
4015 * @private |
|
4016 * @param {Object} object The object to clone. |
|
4017 * @param {string} tag The `toStringTag` of the object to clone. |
|
4018 * @param {boolean} [isDeep] Specify a deep clone. |
|
4019 * @returns {Object} Returns the initialized clone. |
|
4020 */ |
|
4021 function initCloneByTag(object, tag, isDeep) { |
|
4022 var Ctor = object.constructor; |
|
4023 switch (tag) { |
|
4024 case arrayBufferTag: |
|
4025 return bufferClone(object); |
|
4026 |
|
4027 case boolTag: |
|
4028 case dateTag: |
|
4029 return new Ctor(+object); |
|
4030 |
|
4031 case float32Tag: case float64Tag: |
|
4032 case int8Tag: case int16Tag: case int32Tag: |
|
4033 case uint8Tag: case uint8ClampedTag: case uint16Tag: case uint32Tag: |
|
4034 var buffer = object.buffer; |
|
4035 return new Ctor(isDeep ? bufferClone(buffer) : buffer, object.byteOffset, object.length); |
|
4036 |
|
4037 case numberTag: |
|
4038 case stringTag: |
|
4039 return new Ctor(object); |
|
4040 |
|
4041 case regexpTag: |
|
4042 var result = new Ctor(object.source, reFlags.exec(object)); |
|
4043 result.lastIndex = object.lastIndex; |
|
4044 } |
|
4045 return result; |
|
4046 } |
|
4047 |
|
4048 /** |
|
4049 * Invokes the method at `path` on `object`. |
|
4050 * |
|
4051 * @private |
|
4052 * @param {Object} object The object to query. |
|
4053 * @param {Array|string} path The path of the method to invoke. |
|
4054 * @param {Array} args The arguments to invoke the method with. |
|
4055 * @returns {*} Returns the result of the invoked method. |
|
4056 */ |
|
4057 function invokePath(object, path, args) { |
|
4058 if (object != null && !isKey(path, object)) { |
|
4059 path = toPath(path); |
|
4060 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
|
4061 path = last(path); |
|
4062 } |
|
4063 var func = object == null ? object : object[path]; |
|
4064 return func == null ? undefined : func.apply(object, args); |
|
4065 } |
|
4066 |
|
4067 /** |
|
4068 * Checks if `value` is array-like. |
1478 * |
4069 * |
1479 * @private |
4070 * @private |
1480 * @param {*} value The value to check. |
4071 * @param {*} value The value to check. |
1481 * @returns {boolean} Returns `true` if the `value` is a native function, else `false`. |
4072 * @returns {boolean} Returns `true` if `value` is array-like, else `false`. |
1482 */ |
4073 */ |
1483 function isNative(value) { |
4074 function isArrayLike(value) { |
1484 return typeof value == 'function' && reNative.test(value); |
4075 return value != null && isLength(getLength(value)); |
1485 } |
4076 } |
1486 |
4077 |
1487 /** |
4078 /** |
1488 * Sets `this` binding data on a given function. |
4079 * Checks if `value` is a valid array-like index. |
1489 * |
|
1490 * @private |
|
1491 * @param {Function} func The function to set data on. |
|
1492 * @param {Array} value The data array to set. |
|
1493 */ |
|
1494 var setBindData = !defineProperty ? noop : function(func, value) { |
|
1495 descriptor.value = value; |
|
1496 defineProperty(func, '__bindData__', descriptor); |
|
1497 descriptor.value = null; |
|
1498 }; |
|
1499 |
|
1500 /** |
|
1501 * A fallback implementation of `isPlainObject` which checks if a given value |
|
1502 * is an object created by the `Object` constructor, assuming objects created |
|
1503 * by the `Object` constructor have no inherited enumerable properties and that |
|
1504 * there are no `Object.prototype` extensions. |
|
1505 * |
4080 * |
1506 * @private |
4081 * @private |
1507 * @param {*} value The value to check. |
4082 * @param {*} value The value to check. |
1508 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
4083 * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. |
1509 */ |
4084 * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. |
1510 function shimIsPlainObject(value) { |
4085 */ |
1511 var ctor, |
4086 function isIndex(value, length) { |
1512 result; |
4087 value = (typeof value == 'number' || reIsUint.test(value)) ? +value : -1; |
1513 |
4088 length = length == null ? MAX_SAFE_INTEGER : length; |
1514 // avoid non Object objects, `arguments` objects, and DOM elements |
4089 return value > -1 && value % 1 == 0 && value < length; |
1515 if (!(value && toString.call(value) == objectClass) || |
4090 } |
1516 (ctor = value.constructor, isFunction(ctor) && !(ctor instanceof ctor))) { |
4091 |
|
4092 /** |
|
4093 * Checks if the provided arguments are from an iteratee call. |
|
4094 * |
|
4095 * @private |
|
4096 * @param {*} value The potential iteratee value argument. |
|
4097 * @param {*} index The potential iteratee index or key argument. |
|
4098 * @param {*} object The potential iteratee object argument. |
|
4099 * @returns {boolean} Returns `true` if the arguments are from an iteratee call, else `false`. |
|
4100 */ |
|
4101 function isIterateeCall(value, index, object) { |
|
4102 if (!isObject(object)) { |
1517 return false; |
4103 return false; |
1518 } |
4104 } |
1519 // In most environments an object's own properties are iterated before |
4105 var type = typeof index; |
1520 // its inherited properties. If the last iterated property is an object's |
4106 if (type == 'number' |
1521 // own property then there are no inherited enumerable properties. |
4107 ? (isArrayLike(object) && isIndex(index, object.length)) |
1522 forIn(value, function(value, key) { |
4108 : (type == 'string' && index in object)) { |
1523 result = key; |
4109 var other = object[index]; |
1524 }); |
4110 return value === value ? (value === other) : (other !== other); |
1525 return typeof result == 'undefined' || hasOwnProperty.call(value, result); |
4111 } |
1526 } |
4112 return false; |
1527 |
4113 } |
1528 /** |
4114 |
1529 * Used by `unescape` to convert HTML entities to characters. |
4115 /** |
1530 * |
4116 * Checks if `value` is a property name and not a property path. |
1531 * @private |
4117 * |
1532 * @param {string} match The matched character to unescape. |
4118 * @private |
1533 * @returns {string} Returns the unescaped character. |
|
1534 */ |
|
1535 function unescapeHtmlChar(match) { |
|
1536 return htmlUnescapes[match]; |
|
1537 } |
|
1538 |
|
1539 /*--------------------------------------------------------------------------*/ |
|
1540 |
|
1541 /** |
|
1542 * Checks if `value` is an `arguments` object. |
|
1543 * |
|
1544 * @static |
|
1545 * @memberOf _ |
|
1546 * @category Objects |
|
1547 * @param {*} value The value to check. |
4119 * @param {*} value The value to check. |
1548 * @returns {boolean} Returns `true` if the `value` is an `arguments` object, else `false`. |
4120 * @param {Object} [object] The object to query keys on. |
1549 * @example |
4121 * @returns {boolean} Returns `true` if `value` is a property name, else `false`. |
1550 * |
4122 */ |
1551 * (function() { return _.isArguments(arguments); })(1, 2, 3); |
4123 function isKey(value, object) { |
1552 * // => true |
4124 var type = typeof value; |
1553 * |
4125 if ((type == 'string' && reIsPlainProp.test(value)) || type == 'number') { |
1554 * _.isArguments([1, 2, 3]); |
4126 return true; |
1555 * // => false |
4127 } |
1556 */ |
4128 if (isArray(value)) { |
1557 function isArguments(value) { |
4129 return false; |
1558 return value && typeof value == 'object' && typeof value.length == 'number' && |
4130 } |
1559 toString.call(value) == argsClass || false; |
4131 var result = !reIsDeepProp.test(value); |
1560 } |
4132 return result || (object != null && value in toObject(object)); |
1561 |
4133 } |
1562 /** |
4134 |
1563 * Checks if `value` is an array. |
4135 /** |
1564 * |
4136 * Checks if `func` has a lazy counterpart. |
1565 * @static |
4137 * |
1566 * @memberOf _ |
4138 * @private |
1567 * @type Function |
4139 * @param {Function} func The function to check. |
1568 * @category Objects |
4140 * @returns {boolean} Returns `true` if `func` has a lazy counterpart, else `false`. |
|
4141 */ |
|
4142 function isLaziable(func) { |
|
4143 var funcName = getFuncName(func), |
|
4144 other = lodash[funcName]; |
|
4145 |
|
4146 if (typeof other != 'function' || !(funcName in LazyWrapper.prototype)) { |
|
4147 return false; |
|
4148 } |
|
4149 if (func === other) { |
|
4150 return true; |
|
4151 } |
|
4152 var data = getData(other); |
|
4153 return !!data && func === data[0]; |
|
4154 } |
|
4155 |
|
4156 /** |
|
4157 * Checks if `value` is a valid array-like length. |
|
4158 * |
|
4159 * **Note:** This function is based on [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). |
|
4160 * |
|
4161 * @private |
1569 * @param {*} value The value to check. |
4162 * @param {*} value The value to check. |
1570 * @returns {boolean} Returns `true` if the `value` is an array, else `false`. |
4163 * @returns {boolean} Returns `true` if `value` is a valid length, else `false`. |
1571 * @example |
4164 */ |
1572 * |
4165 function isLength(value) { |
1573 * (function() { return _.isArray(arguments); })(); |
4166 return typeof value == 'number' && value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; |
1574 * // => false |
4167 } |
1575 * |
4168 |
1576 * _.isArray([1, 2, 3]); |
4169 /** |
1577 * // => true |
4170 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. |
1578 */ |
4171 * |
1579 var isArray = nativeIsArray || function(value) { |
4172 * @private |
1580 return value && typeof value == 'object' && typeof value.length == 'number' && |
4173 * @param {*} value The value to check. |
1581 toString.call(value) == arrayClass || false; |
4174 * @returns {boolean} Returns `true` if `value` if suitable for strict |
1582 }; |
4175 * equality comparisons, else `false`. |
1583 |
4176 */ |
1584 /** |
4177 function isStrictComparable(value) { |
1585 * A fallback implementation of `Object.keys` which produces an array of the |
4178 return value === value && !isObject(value); |
1586 * given object's own enumerable property names. |
4179 } |
1587 * |
4180 |
1588 * @private |
4181 /** |
1589 * @type Function |
4182 * Merges the function metadata of `source` into `data`. |
1590 * @param {Object} object The object to inspect. |
4183 * |
1591 * @returns {Array} Returns an array of property names. |
4184 * Merging metadata reduces the number of wrappers required to invoke a function. |
1592 */ |
4185 * This is possible because methods like `_.bind`, `_.curry`, and `_.partial` |
1593 var shimKeys = function(object) { |
4186 * may be applied regardless of execution order. Methods like `_.ary` and `_.rearg` |
1594 var index, iterable = object, result = []; |
4187 * augment function arguments, making the order in which they are executed important, |
1595 if (!iterable) return result; |
4188 * preventing the merging of metadata. However, we make an exception for a safe |
1596 if (!(objectTypes[typeof object])) return result; |
4189 * common case where curried functions have `_.ary` and or `_.rearg` applied. |
1597 for (index in iterable) { |
4190 * |
1598 if (hasOwnProperty.call(iterable, index)) { |
4191 * @private |
1599 result.push(index); |
4192 * @param {Array} data The destination metadata. |
1600 } |
4193 * @param {Array} source The source metadata. |
1601 } |
4194 * @returns {Array} Returns `data`. |
1602 return result |
4195 */ |
1603 }; |
4196 function mergeData(data, source) { |
1604 |
4197 var bitmask = data[1], |
1605 /** |
4198 srcBitmask = source[1], |
1606 * Creates an array composed of the own enumerable property names of an object. |
4199 newBitmask = bitmask | srcBitmask, |
1607 * |
4200 isCommon = newBitmask < ARY_FLAG; |
1608 * @static |
4201 |
1609 * @memberOf _ |
4202 var isCombo = |
1610 * @category Objects |
4203 (srcBitmask == ARY_FLAG && bitmask == CURRY_FLAG) || |
1611 * @param {Object} object The object to inspect. |
4204 (srcBitmask == ARY_FLAG && bitmask == REARG_FLAG && data[7].length <= source[8]) || |
1612 * @returns {Array} Returns an array of property names. |
4205 (srcBitmask == (ARY_FLAG | REARG_FLAG) && bitmask == CURRY_FLAG); |
1613 * @example |
4206 |
1614 * |
4207 // Exit early if metadata can't be merged. |
1615 * _.keys({ 'one': 1, 'two': 2, 'three': 3 }); |
4208 if (!(isCommon || isCombo)) { |
1616 * // => ['one', 'two', 'three'] (property order is not guaranteed across environments) |
4209 return data; |
1617 */ |
4210 } |
1618 var keys = !nativeKeys ? shimKeys : function(object) { |
4211 // Use source `thisArg` if available. |
1619 if (!isObject(object)) { |
4212 if (srcBitmask & BIND_FLAG) { |
1620 return []; |
4213 data[2] = source[2]; |
1621 } |
4214 // Set when currying a bound function. |
1622 return nativeKeys(object); |
4215 newBitmask |= (bitmask & BIND_FLAG) ? 0 : CURRY_BOUND_FLAG; |
1623 }; |
4216 } |
1624 |
4217 // Compose partial arguments. |
1625 /** |
4218 var value = source[3]; |
1626 * Used to convert characters to HTML entities: |
4219 if (value) { |
1627 * |
4220 var partials = data[3]; |
1628 * Though the `>` character is escaped for symmetry, characters like `>` and `/` |
4221 data[3] = partials ? composeArgs(partials, value, source[4]) : arrayCopy(value); |
1629 * don't require escaping in HTML and have no special meaning unless they're part |
4222 data[4] = partials ? replaceHolders(data[3], PLACEHOLDER) : arrayCopy(source[4]); |
1630 * of a tag or an unquoted attribute value. |
4223 } |
1631 * http://mathiasbynens.be/notes/ambiguous-ampersands (under "semi-related fun fact") |
4224 // Compose partial right arguments. |
1632 */ |
4225 value = source[5]; |
1633 var htmlEscapes = { |
4226 if (value) { |
1634 '&': '&', |
4227 partials = data[5]; |
1635 '<': '<', |
4228 data[5] = partials ? composeArgsRight(partials, value, source[6]) : arrayCopy(value); |
1636 '>': '>', |
4229 data[6] = partials ? replaceHolders(data[5], PLACEHOLDER) : arrayCopy(source[6]); |
1637 '"': '"', |
4230 } |
1638 "'": ''' |
4231 // Use source `argPos` if available. |
1639 }; |
4232 value = source[7]; |
1640 |
4233 if (value) { |
1641 /** Used to convert HTML entities to characters */ |
4234 data[7] = arrayCopy(value); |
1642 var htmlUnescapes = invert(htmlEscapes); |
4235 } |
1643 |
4236 // Use source `ary` if it's smaller. |
1644 /** Used to match HTML entities and HTML characters */ |
4237 if (srcBitmask & ARY_FLAG) { |
1645 var reEscapedHtml = RegExp('(' + keys(htmlUnescapes).join('|') + ')', 'g'), |
4238 data[8] = data[8] == null ? source[8] : nativeMin(data[8], source[8]); |
1646 reUnescapedHtml = RegExp('[' + keys(htmlEscapes).join('') + ']', 'g'); |
4239 } |
1647 |
4240 // Use source `arity` if one is not provided. |
1648 /*--------------------------------------------------------------------------*/ |
4241 if (data[9] == null) { |
1649 |
4242 data[9] = source[9]; |
1650 /** |
4243 } |
1651 * Assigns own enumerable properties of source object(s) to the destination |
4244 // Use source `func` and merge bitmasks. |
1652 * object. Subsequent sources will overwrite property assignments of previous |
4245 data[0] = source[0]; |
1653 * sources. If a callback is provided it will be executed to produce the |
4246 data[1] = newBitmask; |
1654 * assigned values. The callback is bound to `thisArg` and invoked with two |
4247 |
1655 * arguments; (objectValue, sourceValue). |
4248 return data; |
1656 * |
4249 } |
1657 * @static |
4250 |
1658 * @memberOf _ |
4251 /** |
1659 * @type Function |
4252 * Used by `_.defaultsDeep` to customize its `_.merge` use. |
1660 * @alias extend |
4253 * |
1661 * @category Objects |
4254 * @private |
1662 * @param {Object} object The destination object. |
4255 * @param {*} objectValue The destination object property value. |
1663 * @param {...Object} [source] The source objects. |
4256 * @param {*} sourceValue The source object property value. |
1664 * @param {Function} [callback] The function to customize assigning values. |
4257 * @returns {*} Returns the value to assign to the destination object. |
1665 * @param {*} [thisArg] The `this` binding of `callback`. |
4258 */ |
1666 * @returns {Object} Returns the destination object. |
4259 function mergeDefaults(objectValue, sourceValue) { |
1667 * @example |
4260 return objectValue === undefined ? sourceValue : merge(objectValue, sourceValue, mergeDefaults); |
1668 * |
4261 } |
1669 * _.assign({ 'name': 'fred' }, { 'employer': 'slate' }); |
4262 |
1670 * // => { 'name': 'fred', 'employer': 'slate' } |
4263 /** |
1671 * |
4264 * A specialized version of `_.pick` which picks `object` properties specified |
1672 * var defaults = _.partialRight(_.assign, function(a, b) { |
4265 * by `props`. |
1673 * return typeof a == 'undefined' ? b : a; |
4266 * |
1674 * }); |
4267 * @private |
1675 * |
4268 * @param {Object} object The source object. |
1676 * var object = { 'name': 'barney' }; |
4269 * @param {string[]} props The property names to pick. |
1677 * defaults(object, { 'name': 'fred', 'employer': 'slate' }); |
|
1678 * // => { 'name': 'barney', 'employer': 'slate' } |
|
1679 */ |
|
1680 var assign = function(object, source, guard) { |
|
1681 var index, iterable = object, result = iterable; |
|
1682 if (!iterable) return result; |
|
1683 var args = arguments, |
|
1684 argsIndex = 0, |
|
1685 argsLength = typeof guard == 'number' ? 2 : args.length; |
|
1686 if (argsLength > 3 && typeof args[argsLength - 2] == 'function') { |
|
1687 var callback = baseCreateCallback(args[--argsLength - 1], args[argsLength--], 2); |
|
1688 } else if (argsLength > 2 && typeof args[argsLength - 1] == 'function') { |
|
1689 callback = args[--argsLength]; |
|
1690 } |
|
1691 while (++argsIndex < argsLength) { |
|
1692 iterable = args[argsIndex]; |
|
1693 if (iterable && objectTypes[typeof iterable]) { |
|
1694 var ownIndex = -1, |
|
1695 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
1696 length = ownProps ? ownProps.length : 0; |
|
1697 |
|
1698 while (++ownIndex < length) { |
|
1699 index = ownProps[ownIndex]; |
|
1700 result[index] = callback ? callback(result[index], iterable[index]) : iterable[index]; |
|
1701 } |
|
1702 } |
|
1703 } |
|
1704 return result |
|
1705 }; |
|
1706 |
|
1707 /** |
|
1708 * Creates a clone of `value`. If `isDeep` is `true` nested objects will also |
|
1709 * be cloned, otherwise they will be assigned by reference. If a callback |
|
1710 * is provided it will be executed to produce the cloned values. If the |
|
1711 * callback returns `undefined` cloning will be handled by the method instead. |
|
1712 * The callback is bound to `thisArg` and invoked with one argument; (value). |
|
1713 * |
|
1714 * @static |
|
1715 * @memberOf _ |
|
1716 * @category Objects |
|
1717 * @param {*} value The value to clone. |
|
1718 * @param {boolean} [isDeep=false] Specify a deep clone. |
|
1719 * @param {Function} [callback] The function to customize cloning values. |
|
1720 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1721 * @returns {*} Returns the cloned value. |
|
1722 * @example |
|
1723 * |
|
1724 * var characters = [ |
|
1725 * { 'name': 'barney', 'age': 36 }, |
|
1726 * { 'name': 'fred', 'age': 40 } |
|
1727 * ]; |
|
1728 * |
|
1729 * var shallow = _.clone(characters); |
|
1730 * shallow[0] === characters[0]; |
|
1731 * // => true |
|
1732 * |
|
1733 * var deep = _.clone(characters, true); |
|
1734 * deep[0] === characters[0]; |
|
1735 * // => false |
|
1736 * |
|
1737 * _.mixin({ |
|
1738 * 'clone': _.partialRight(_.clone, function(value) { |
|
1739 * return _.isElement(value) ? value.cloneNode(false) : undefined; |
|
1740 * }) |
|
1741 * }); |
|
1742 * |
|
1743 * var clone = _.clone(document.body); |
|
1744 * clone.childNodes.length; |
|
1745 * // => 0 |
|
1746 */ |
|
1747 function clone(value, isDeep, callback, thisArg) { |
|
1748 // allows working with "Collections" methods without using their `index` |
|
1749 // and `collection` arguments for `isDeep` and `callback` |
|
1750 if (typeof isDeep != 'boolean' && isDeep != null) { |
|
1751 thisArg = callback; |
|
1752 callback = isDeep; |
|
1753 isDeep = false; |
|
1754 } |
|
1755 return baseClone(value, isDeep, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); |
|
1756 } |
|
1757 |
|
1758 /** |
|
1759 * Creates a deep clone of `value`. If a callback is provided it will be |
|
1760 * executed to produce the cloned values. If the callback returns `undefined` |
|
1761 * cloning will be handled by the method instead. The callback is bound to |
|
1762 * `thisArg` and invoked with one argument; (value). |
|
1763 * |
|
1764 * Note: This method is loosely based on the structured clone algorithm. Functions |
|
1765 * and DOM nodes are **not** cloned. The enumerable properties of `arguments` objects and |
|
1766 * objects created by constructors other than `Object` are cloned to plain `Object` objects. |
|
1767 * See http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm. |
|
1768 * |
|
1769 * @static |
|
1770 * @memberOf _ |
|
1771 * @category Objects |
|
1772 * @param {*} value The value to deep clone. |
|
1773 * @param {Function} [callback] The function to customize cloning values. |
|
1774 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1775 * @returns {*} Returns the deep cloned value. |
|
1776 * @example |
|
1777 * |
|
1778 * var characters = [ |
|
1779 * { 'name': 'barney', 'age': 36 }, |
|
1780 * { 'name': 'fred', 'age': 40 } |
|
1781 * ]; |
|
1782 * |
|
1783 * var deep = _.cloneDeep(characters); |
|
1784 * deep[0] === characters[0]; |
|
1785 * // => false |
|
1786 * |
|
1787 * var view = { |
|
1788 * 'label': 'docs', |
|
1789 * 'node': element |
|
1790 * }; |
|
1791 * |
|
1792 * var clone = _.cloneDeep(view, function(value) { |
|
1793 * return _.isElement(value) ? value.cloneNode(true) : undefined; |
|
1794 * }); |
|
1795 * |
|
1796 * clone.node == view.node; |
|
1797 * // => false |
|
1798 */ |
|
1799 function cloneDeep(value, callback, thisArg) { |
|
1800 return baseClone(value, true, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 1)); |
|
1801 } |
|
1802 |
|
1803 /** |
|
1804 * Creates an object that inherits from the given `prototype` object. If a |
|
1805 * `properties` object is provided its own enumerable properties are assigned |
|
1806 * to the created object. |
|
1807 * |
|
1808 * @static |
|
1809 * @memberOf _ |
|
1810 * @category Objects |
|
1811 * @param {Object} prototype The object to inherit from. |
|
1812 * @param {Object} [properties] The properties to assign to the object. |
|
1813 * @returns {Object} Returns the new object. |
4270 * @returns {Object} Returns the new object. |
1814 * @example |
4271 */ |
1815 * |
4272 function pickByArray(object, props) { |
1816 * function Shape() { |
4273 object = toObject(object); |
1817 * this.x = 0; |
4274 |
1818 * this.y = 0; |
4275 var index = -1, |
1819 * } |
4276 length = props.length, |
1820 * |
4277 result = {}; |
1821 * function Circle() { |
4278 |
1822 * Shape.call(this); |
4279 while (++index < length) { |
1823 * } |
4280 var key = props[index]; |
1824 * |
4281 if (key in object) { |
1825 * Circle.prototype = _.create(Shape.prototype, { 'constructor': Circle }); |
4282 result[key] = object[key]; |
1826 * |
4283 } |
1827 * var circle = new Circle; |
4284 } |
1828 * circle instanceof Circle; |
4285 return result; |
1829 * // => true |
4286 } |
1830 * |
4287 |
1831 * circle instanceof Shape; |
4288 /** |
1832 * // => true |
4289 * A specialized version of `_.pick` which picks `object` properties `predicate` |
1833 */ |
4290 * returns truthy for. |
1834 function create(prototype, properties) { |
4291 * |
1835 var result = baseCreate(prototype); |
4292 * @private |
1836 return properties ? assign(result, properties) : result; |
4293 * @param {Object} object The source object. |
1837 } |
4294 * @param {Function} predicate The function invoked per iteration. |
1838 |
4295 * @returns {Object} Returns the new object. |
1839 /** |
4296 */ |
1840 * Assigns own enumerable properties of source object(s) to the destination |
4297 function pickByCallback(object, predicate) { |
1841 * object for all destination properties that resolve to `undefined`. Once a |
4298 var result = {}; |
1842 * property is set, additional defaults of the same property will be ignored. |
4299 baseForIn(object, function(value, key, object) { |
1843 * |
4300 if (predicate(value, key, object)) { |
1844 * @static |
4301 result[key] = value; |
1845 * @memberOf _ |
|
1846 * @type Function |
|
1847 * @category Objects |
|
1848 * @param {Object} object The destination object. |
|
1849 * @param {...Object} [source] The source objects. |
|
1850 * @param- {Object} [guard] Allows working with `_.reduce` without using its |
|
1851 * `key` and `object` arguments as sources. |
|
1852 * @returns {Object} Returns the destination object. |
|
1853 * @example |
|
1854 * |
|
1855 * var object = { 'name': 'barney' }; |
|
1856 * _.defaults(object, { 'name': 'fred', 'employer': 'slate' }); |
|
1857 * // => { 'name': 'barney', 'employer': 'slate' } |
|
1858 */ |
|
1859 var defaults = function(object, source, guard) { |
|
1860 var index, iterable = object, result = iterable; |
|
1861 if (!iterable) return result; |
|
1862 var args = arguments, |
|
1863 argsIndex = 0, |
|
1864 argsLength = typeof guard == 'number' ? 2 : args.length; |
|
1865 while (++argsIndex < argsLength) { |
|
1866 iterable = args[argsIndex]; |
|
1867 if (iterable && objectTypes[typeof iterable]) { |
|
1868 var ownIndex = -1, |
|
1869 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
1870 length = ownProps ? ownProps.length : 0; |
|
1871 |
|
1872 while (++ownIndex < length) { |
|
1873 index = ownProps[ownIndex]; |
|
1874 if (typeof result[index] == 'undefined') result[index] = iterable[index]; |
|
1875 } |
|
1876 } |
|
1877 } |
|
1878 return result |
|
1879 }; |
|
1880 |
|
1881 /** |
|
1882 * This method is like `_.findIndex` except that it returns the key of the |
|
1883 * first element that passes the callback check, instead of the element itself. |
|
1884 * |
|
1885 * If a property name is provided for `callback` the created "_.pluck" style |
|
1886 * callback will return the property value of the given element. |
|
1887 * |
|
1888 * If an object is provided for `callback` the created "_.where" style callback |
|
1889 * will return `true` for elements that have the properties of the given object, |
|
1890 * else `false`. |
|
1891 * |
|
1892 * @static |
|
1893 * @memberOf _ |
|
1894 * @category Objects |
|
1895 * @param {Object} object The object to search. |
|
1896 * @param {Function|Object|string} [callback=identity] The function called per |
|
1897 * iteration. If a property name or object is provided it will be used to |
|
1898 * create a "_.pluck" or "_.where" style callback, respectively. |
|
1899 * @param {*} [thisArg] The `this` binding of `callback`. |
|
1900 * @returns {string|undefined} Returns the key of the found element, else `undefined`. |
|
1901 * @example |
|
1902 * |
|
1903 * var characters = { |
|
1904 * 'barney': { 'age': 36, 'blocked': false }, |
|
1905 * 'fred': { 'age': 40, 'blocked': true }, |
|
1906 * 'pebbles': { 'age': 1, 'blocked': false } |
|
1907 * }; |
|
1908 * |
|
1909 * _.findKey(characters, function(chr) { |
|
1910 * return chr.age < 40; |
|
1911 * }); |
|
1912 * // => 'barney' (property order is not guaranteed across environments) |
|
1913 * |
|
1914 * // using "_.where" callback shorthand |
|
1915 * _.findKey(characters, { 'age': 1 }); |
|
1916 * // => 'pebbles' |
|
1917 * |
|
1918 * // using "_.pluck" callback shorthand |
|
1919 * _.findKey(characters, 'blocked'); |
|
1920 * // => 'fred' |
|
1921 */ |
|
1922 function findKey(object, callback, thisArg) { |
|
1923 var result; |
|
1924 callback = lodash.createCallback(callback, thisArg, 3); |
|
1925 forOwn(object, function(value, key, object) { |
|
1926 if (callback(value, key, object)) { |
|
1927 result = key; |
|
1928 return false; |
|
1929 } |
4302 } |
1930 }); |
4303 }); |
1931 return result; |
4304 return result; |
1932 } |
4305 } |
1933 |
4306 |
1934 /** |
4307 /** |
1935 * This method is like `_.findKey` except that it iterates over elements |
4308 * Reorder `array` according to the specified indexes where the element at |
1936 * of a `collection` in the opposite order. |
4309 * the first index is assigned as the first element, the element at |
1937 * |
4310 * the second index is assigned as the second element, and so on. |
1938 * If a property name is provided for `callback` the created "_.pluck" style |
4311 * |
1939 * callback will return the property value of the given element. |
4312 * @private |
1940 * |
4313 * @param {Array} array The array to reorder. |
1941 * If an object is provided for `callback` the created "_.where" style callback |
4314 * @param {Array} indexes The arranged array indexes. |
1942 * will return `true` for elements that have the properties of the given object, |
4315 * @returns {Array} Returns `array`. |
1943 * else `false`. |
4316 */ |
1944 * |
4317 function reorder(array, indexes) { |
1945 * @static |
4318 var arrLength = array.length, |
1946 * @memberOf _ |
4319 length = nativeMin(indexes.length, arrLength), |
1947 * @category Objects |
4320 oldArray = arrayCopy(array); |
1948 * @param {Object} object The object to search. |
4321 |
1949 * @param {Function|Object|string} [callback=identity] The function called per |
4322 while (length--) { |
1950 * iteration. If a property name or object is provided it will be used to |
4323 var index = indexes[length]; |
1951 * create a "_.pluck" or "_.where" style callback, respectively. |
4324 array[length] = isIndex(index, arrLength) ? oldArray[index] : undefined; |
1952 * @param {*} [thisArg] The `this` binding of `callback`. |
4325 } |
1953 * @returns {string|undefined} Returns the key of the found element, else `undefined`. |
4326 return array; |
1954 * @example |
4327 } |
1955 * |
4328 |
1956 * var characters = { |
4329 /** |
1957 * 'barney': { 'age': 36, 'blocked': true }, |
4330 * Sets metadata for `func`. |
1958 * 'fred': { 'age': 40, 'blocked': false }, |
4331 * |
1959 * 'pebbles': { 'age': 1, 'blocked': true } |
4332 * **Note:** If this function becomes hot, i.e. is invoked a lot in a short |
1960 * }; |
4333 * period of time, it will trip its breaker and transition to an identity function |
1961 * |
4334 * to avoid garbage collection pauses in V8. See [V8 issue 2070](https://code.google.com/p/v8/issues/detail?id=2070) |
1962 * _.findLastKey(characters, function(chr) { |
4335 * for more details. |
1963 * return chr.age < 40; |
4336 * |
1964 * }); |
4337 * @private |
1965 * // => returns `pebbles`, assuming `_.findKey` returns `barney` |
4338 * @param {Function} func The function to associate metadata with. |
1966 * |
4339 * @param {*} data The metadata. |
1967 * // using "_.where" callback shorthand |
4340 * @returns {Function} Returns `func`. |
1968 * _.findLastKey(characters, { 'age': 40 }); |
4341 */ |
1969 * // => 'fred' |
4342 var setData = (function() { |
1970 * |
4343 var count = 0, |
1971 * // using "_.pluck" callback shorthand |
4344 lastCalled = 0; |
1972 * _.findLastKey(characters, 'blocked'); |
4345 |
1973 * // => 'pebbles' |
4346 return function(key, value) { |
1974 */ |
4347 var stamp = now(), |
1975 function findLastKey(object, callback, thisArg) { |
4348 remaining = HOT_SPAN - (stamp - lastCalled); |
1976 var result; |
4349 |
1977 callback = lodash.createCallback(callback, thisArg, 3); |
4350 lastCalled = stamp; |
1978 forOwnRight(object, function(value, key, object) { |
4351 if (remaining > 0) { |
1979 if (callback(value, key, object)) { |
4352 if (++count >= HOT_COUNT) { |
1980 result = key; |
4353 return key; |
1981 return false; |
4354 } |
1982 } |
4355 } else { |
|
4356 count = 0; |
|
4357 } |
|
4358 return baseSetData(key, value); |
|
4359 }; |
|
4360 }()); |
|
4361 |
|
4362 /** |
|
4363 * A fallback implementation of `Object.keys` which creates an array of the |
|
4364 * own enumerable property names of `object`. |
|
4365 * |
|
4366 * @private |
|
4367 * @param {Object} object The object to query. |
|
4368 * @returns {Array} Returns the array of property names. |
|
4369 */ |
|
4370 function shimKeys(object) { |
|
4371 var props = keysIn(object), |
|
4372 propsLength = props.length, |
|
4373 length = propsLength && object.length; |
|
4374 |
|
4375 var allowIndexes = !!length && isLength(length) && |
|
4376 (isArray(object) || isArguments(object)); |
|
4377 |
|
4378 var index = -1, |
|
4379 result = []; |
|
4380 |
|
4381 while (++index < propsLength) { |
|
4382 var key = props[index]; |
|
4383 if ((allowIndexes && isIndex(key, length)) || hasOwnProperty.call(object, key)) { |
|
4384 result.push(key); |
|
4385 } |
|
4386 } |
|
4387 return result; |
|
4388 } |
|
4389 |
|
4390 /** |
|
4391 * Converts `value` to an array-like object if it's not one. |
|
4392 * |
|
4393 * @private |
|
4394 * @param {*} value The value to process. |
|
4395 * @returns {Array|Object} Returns the array-like object. |
|
4396 */ |
|
4397 function toIterable(value) { |
|
4398 if (value == null) { |
|
4399 return []; |
|
4400 } |
|
4401 if (!isArrayLike(value)) { |
|
4402 return values(value); |
|
4403 } |
|
4404 return isObject(value) ? value : Object(value); |
|
4405 } |
|
4406 |
|
4407 /** |
|
4408 * Converts `value` to an object if it's not one. |
|
4409 * |
|
4410 * @private |
|
4411 * @param {*} value The value to process. |
|
4412 * @returns {Object} Returns the object. |
|
4413 */ |
|
4414 function toObject(value) { |
|
4415 return isObject(value) ? value : Object(value); |
|
4416 } |
|
4417 |
|
4418 /** |
|
4419 * Converts `value` to property path array if it's not one. |
|
4420 * |
|
4421 * @private |
|
4422 * @param {*} value The value to process. |
|
4423 * @returns {Array} Returns the property path array. |
|
4424 */ |
|
4425 function toPath(value) { |
|
4426 if (isArray(value)) { |
|
4427 return value; |
|
4428 } |
|
4429 var result = []; |
|
4430 baseToString(value).replace(rePropName, function(match, number, quote, string) { |
|
4431 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match)); |
1983 }); |
4432 }); |
1984 return result; |
4433 return result; |
1985 } |
4434 } |
1986 |
4435 |
1987 /** |
4436 /** |
1988 * Iterates over own and inherited enumerable properties of an object, |
4437 * Creates a clone of `wrapper`. |
1989 * executing the callback for each property. The callback is bound to `thisArg` |
4438 * |
1990 * and invoked with three arguments; (value, key, object). Callbacks may exit |
4439 * @private |
1991 * iteration early by explicitly returning `false`. |
4440 * @param {Object} wrapper The wrapper to clone. |
1992 * |
4441 * @returns {Object} Returns the cloned wrapper. |
1993 * @static |
4442 */ |
1994 * @memberOf _ |
4443 function wrapperClone(wrapper) { |
1995 * @type Function |
4444 return wrapper instanceof LazyWrapper |
1996 * @category Objects |
4445 ? wrapper.clone() |
1997 * @param {Object} object The object to iterate over. |
4446 : new LodashWrapper(wrapper.__wrapped__, wrapper.__chain__, arrayCopy(wrapper.__actions__)); |
1998 * @param {Function} [callback=identity] The function called per iteration. |
4447 } |
1999 * @param {*} [thisArg] The `this` binding of `callback`. |
4448 |
2000 * @returns {Object} Returns `object`. |
4449 /*------------------------------------------------------------------------*/ |
2001 * @example |
4450 |
2002 * |
4451 /** |
2003 * function Shape() { |
4452 * Creates an array of elements split into groups the length of `size`. |
2004 * this.x = 0; |
4453 * If `collection` can't be split evenly, the final chunk will be the remaining |
2005 * this.y = 0; |
4454 * elements. |
2006 * } |
4455 * |
2007 * |
4456 * @static |
2008 * Shape.prototype.move = function(x, y) { |
4457 * @memberOf _ |
2009 * this.x += x; |
4458 * @category Array |
2010 * this.y += y; |
4459 * @param {Array} array The array to process. |
2011 * }; |
4460 * @param {number} [size=1] The length of each chunk. |
2012 * |
4461 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
2013 * _.forIn(new Shape, function(value, key) { |
4462 * @returns {Array} Returns the new array containing chunks. |
2014 * console.log(key); |
4463 * @example |
2015 * }); |
4464 * |
2016 * // => logs 'x', 'y', and 'move' (property order is not guaranteed across environments) |
4465 * _.chunk(['a', 'b', 'c', 'd'], 2); |
2017 */ |
4466 * // => [['a', 'b'], ['c', 'd']] |
2018 var forIn = function(collection, callback, thisArg) { |
4467 * |
2019 var index, iterable = collection, result = iterable; |
4468 * _.chunk(['a', 'b', 'c', 'd'], 3); |
2020 if (!iterable) return result; |
4469 * // => [['a', 'b', 'c'], ['d']] |
2021 if (!objectTypes[typeof iterable]) return result; |
4470 */ |
2022 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
4471 function chunk(array, size, guard) { |
2023 for (index in iterable) { |
4472 if (guard ? isIterateeCall(array, size, guard) : size == null) { |
2024 if (callback(iterable[index], index, collection) === false) return result; |
4473 size = 1; |
2025 } |
4474 } else { |
2026 return result |
4475 size = nativeMax(nativeFloor(size) || 1, 1); |
2027 }; |
4476 } |
2028 |
4477 var index = 0, |
2029 /** |
4478 length = array ? array.length : 0, |
2030 * This method is like `_.forIn` except that it iterates over elements |
4479 resIndex = -1, |
2031 * of a `collection` in the opposite order. |
4480 result = Array(nativeCeil(length / size)); |
2032 * |
4481 |
2033 * @static |
4482 while (index < length) { |
2034 * @memberOf _ |
4483 result[++resIndex] = baseSlice(array, index, (index += size)); |
2035 * @category Objects |
|
2036 * @param {Object} object The object to iterate over. |
|
2037 * @param {Function} [callback=identity] The function called per iteration. |
|
2038 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2039 * @returns {Object} Returns `object`. |
|
2040 * @example |
|
2041 * |
|
2042 * function Shape() { |
|
2043 * this.x = 0; |
|
2044 * this.y = 0; |
|
2045 * } |
|
2046 * |
|
2047 * Shape.prototype.move = function(x, y) { |
|
2048 * this.x += x; |
|
2049 * this.y += y; |
|
2050 * }; |
|
2051 * |
|
2052 * _.forInRight(new Shape, function(value, key) { |
|
2053 * console.log(key); |
|
2054 * }); |
|
2055 * // => logs 'move', 'y', and 'x' assuming `_.forIn ` logs 'x', 'y', and 'move' |
|
2056 */ |
|
2057 function forInRight(object, callback, thisArg) { |
|
2058 var pairs = []; |
|
2059 |
|
2060 forIn(object, function(value, key) { |
|
2061 pairs.push(key, value); |
|
2062 }); |
|
2063 |
|
2064 var length = pairs.length; |
|
2065 callback = baseCreateCallback(callback, thisArg, 3); |
|
2066 while (length--) { |
|
2067 if (callback(pairs[length--], pairs[length], object) === false) { |
|
2068 break; |
|
2069 } |
|
2070 } |
|
2071 return object; |
|
2072 } |
|
2073 |
|
2074 /** |
|
2075 * Iterates over own enumerable properties of an object, executing the callback |
|
2076 * for each property. The callback is bound to `thisArg` and invoked with three |
|
2077 * arguments; (value, key, object). Callbacks may exit iteration early by |
|
2078 * explicitly returning `false`. |
|
2079 * |
|
2080 * @static |
|
2081 * @memberOf _ |
|
2082 * @type Function |
|
2083 * @category Objects |
|
2084 * @param {Object} object The object to iterate over. |
|
2085 * @param {Function} [callback=identity] The function called per iteration. |
|
2086 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2087 * @returns {Object} Returns `object`. |
|
2088 * @example |
|
2089 * |
|
2090 * _.forOwn({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { |
|
2091 * console.log(key); |
|
2092 * }); |
|
2093 * // => logs '0', '1', and 'length' (property order is not guaranteed across environments) |
|
2094 */ |
|
2095 var forOwn = function(collection, callback, thisArg) { |
|
2096 var index, iterable = collection, result = iterable; |
|
2097 if (!iterable) return result; |
|
2098 if (!objectTypes[typeof iterable]) return result; |
|
2099 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
2100 var ownIndex = -1, |
|
2101 ownProps = objectTypes[typeof iterable] && keys(iterable), |
|
2102 length = ownProps ? ownProps.length : 0; |
|
2103 |
|
2104 while (++ownIndex < length) { |
|
2105 index = ownProps[ownIndex]; |
|
2106 if (callback(iterable[index], index, collection) === false) return result; |
|
2107 } |
|
2108 return result |
|
2109 }; |
|
2110 |
|
2111 /** |
|
2112 * This method is like `_.forOwn` except that it iterates over elements |
|
2113 * of a `collection` in the opposite order. |
|
2114 * |
|
2115 * @static |
|
2116 * @memberOf _ |
|
2117 * @category Objects |
|
2118 * @param {Object} object The object to iterate over. |
|
2119 * @param {Function} [callback=identity] The function called per iteration. |
|
2120 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2121 * @returns {Object} Returns `object`. |
|
2122 * @example |
|
2123 * |
|
2124 * _.forOwnRight({ '0': 'zero', '1': 'one', 'length': 2 }, function(num, key) { |
|
2125 * console.log(key); |
|
2126 * }); |
|
2127 * // => logs 'length', '1', and '0' assuming `_.forOwn` logs '0', '1', and 'length' |
|
2128 */ |
|
2129 function forOwnRight(object, callback, thisArg) { |
|
2130 var props = keys(object), |
|
2131 length = props.length; |
|
2132 |
|
2133 callback = baseCreateCallback(callback, thisArg, 3); |
|
2134 while (length--) { |
|
2135 var key = props[length]; |
|
2136 if (callback(object[key], key, object) === false) { |
|
2137 break; |
|
2138 } |
|
2139 } |
|
2140 return object; |
|
2141 } |
|
2142 |
|
2143 /** |
|
2144 * Creates a sorted array of property names of all enumerable properties, |
|
2145 * own and inherited, of `object` that have function values. |
|
2146 * |
|
2147 * @static |
|
2148 * @memberOf _ |
|
2149 * @alias methods |
|
2150 * @category Objects |
|
2151 * @param {Object} object The object to inspect. |
|
2152 * @returns {Array} Returns an array of property names that have function values. |
|
2153 * @example |
|
2154 * |
|
2155 * _.functions(_); |
|
2156 * // => ['all', 'any', 'bind', 'bindAll', 'clone', 'compact', 'compose', ...] |
|
2157 */ |
|
2158 function functions(object) { |
|
2159 var result = []; |
|
2160 forIn(object, function(value, key) { |
|
2161 if (isFunction(value)) { |
|
2162 result.push(key); |
|
2163 } |
|
2164 }); |
|
2165 return result.sort(); |
|
2166 } |
|
2167 |
|
2168 /** |
|
2169 * Checks if the specified property name exists as a direct property of `object`, |
|
2170 * instead of an inherited property. |
|
2171 * |
|
2172 * @static |
|
2173 * @memberOf _ |
|
2174 * @category Objects |
|
2175 * @param {Object} object The object to inspect. |
|
2176 * @param {string} key The name of the property to check. |
|
2177 * @returns {boolean} Returns `true` if key is a direct property, else `false`. |
|
2178 * @example |
|
2179 * |
|
2180 * _.has({ 'a': 1, 'b': 2, 'c': 3 }, 'b'); |
|
2181 * // => true |
|
2182 */ |
|
2183 function has(object, key) { |
|
2184 return object ? hasOwnProperty.call(object, key) : false; |
|
2185 } |
|
2186 |
|
2187 /** |
|
2188 * Creates an object composed of the inverted keys and values of the given object. |
|
2189 * |
|
2190 * @static |
|
2191 * @memberOf _ |
|
2192 * @category Objects |
|
2193 * @param {Object} object The object to invert. |
|
2194 * @returns {Object} Returns the created inverted object. |
|
2195 * @example |
|
2196 * |
|
2197 * _.invert({ 'first': 'fred', 'second': 'barney' }); |
|
2198 * // => { 'fred': 'first', 'barney': 'second' } |
|
2199 */ |
|
2200 function invert(object) { |
|
2201 var index = -1, |
|
2202 props = keys(object), |
|
2203 length = props.length, |
|
2204 result = {}; |
|
2205 |
|
2206 while (++index < length) { |
|
2207 var key = props[index]; |
|
2208 result[object[key]] = key; |
|
2209 } |
4484 } |
2210 return result; |
4485 return result; |
2211 } |
4486 } |
2212 |
4487 |
2213 /** |
4488 /** |
2214 * Checks if `value` is a boolean value. |
|
2215 * |
|
2216 * @static |
|
2217 * @memberOf _ |
|
2218 * @category Objects |
|
2219 * @param {*} value The value to check. |
|
2220 * @returns {boolean} Returns `true` if the `value` is a boolean value, else `false`. |
|
2221 * @example |
|
2222 * |
|
2223 * _.isBoolean(null); |
|
2224 * // => false |
|
2225 */ |
|
2226 function isBoolean(value) { |
|
2227 return value === true || value === false || |
|
2228 value && typeof value == 'object' && toString.call(value) == boolClass || false; |
|
2229 } |
|
2230 |
|
2231 /** |
|
2232 * Checks if `value` is a date. |
|
2233 * |
|
2234 * @static |
|
2235 * @memberOf _ |
|
2236 * @category Objects |
|
2237 * @param {*} value The value to check. |
|
2238 * @returns {boolean} Returns `true` if the `value` is a date, else `false`. |
|
2239 * @example |
|
2240 * |
|
2241 * _.isDate(new Date); |
|
2242 * // => true |
|
2243 */ |
|
2244 function isDate(value) { |
|
2245 return value && typeof value == 'object' && toString.call(value) == dateClass || false; |
|
2246 } |
|
2247 |
|
2248 /** |
|
2249 * Checks if `value` is a DOM element. |
|
2250 * |
|
2251 * @static |
|
2252 * @memberOf _ |
|
2253 * @category Objects |
|
2254 * @param {*} value The value to check. |
|
2255 * @returns {boolean} Returns `true` if the `value` is a DOM element, else `false`. |
|
2256 * @example |
|
2257 * |
|
2258 * _.isElement(document.body); |
|
2259 * // => true |
|
2260 */ |
|
2261 function isElement(value) { |
|
2262 return value && value.nodeType === 1 || false; |
|
2263 } |
|
2264 |
|
2265 /** |
|
2266 * Checks if `value` is empty. Arrays, strings, or `arguments` objects with a |
|
2267 * length of `0` and objects with no own enumerable properties are considered |
|
2268 * "empty". |
|
2269 * |
|
2270 * @static |
|
2271 * @memberOf _ |
|
2272 * @category Objects |
|
2273 * @param {Array|Object|string} value The value to inspect. |
|
2274 * @returns {boolean} Returns `true` if the `value` is empty, else `false`. |
|
2275 * @example |
|
2276 * |
|
2277 * _.isEmpty([1, 2, 3]); |
|
2278 * // => false |
|
2279 * |
|
2280 * _.isEmpty({}); |
|
2281 * // => true |
|
2282 * |
|
2283 * _.isEmpty(''); |
|
2284 * // => true |
|
2285 */ |
|
2286 function isEmpty(value) { |
|
2287 var result = true; |
|
2288 if (!value) { |
|
2289 return result; |
|
2290 } |
|
2291 var className = toString.call(value), |
|
2292 length = value.length; |
|
2293 |
|
2294 if ((className == arrayClass || className == stringClass || className == argsClass ) || |
|
2295 (className == objectClass && typeof length == 'number' && isFunction(value.splice))) { |
|
2296 return !length; |
|
2297 } |
|
2298 forOwn(value, function() { |
|
2299 return (result = false); |
|
2300 }); |
|
2301 return result; |
|
2302 } |
|
2303 |
|
2304 /** |
|
2305 * Performs a deep comparison between two values to determine if they are |
|
2306 * equivalent to each other. If a callback is provided it will be executed |
|
2307 * to compare values. If the callback returns `undefined` comparisons will |
|
2308 * be handled by the method instead. The callback is bound to `thisArg` and |
|
2309 * invoked with two arguments; (a, b). |
|
2310 * |
|
2311 * @static |
|
2312 * @memberOf _ |
|
2313 * @category Objects |
|
2314 * @param {*} a The value to compare. |
|
2315 * @param {*} b The other value to compare. |
|
2316 * @param {Function} [callback] The function to customize comparing values. |
|
2317 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2318 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
2319 * @example |
|
2320 * |
|
2321 * var object = { 'name': 'fred' }; |
|
2322 * var copy = { 'name': 'fred' }; |
|
2323 * |
|
2324 * object == copy; |
|
2325 * // => false |
|
2326 * |
|
2327 * _.isEqual(object, copy); |
|
2328 * // => true |
|
2329 * |
|
2330 * var words = ['hello', 'goodbye']; |
|
2331 * var otherWords = ['hi', 'goodbye']; |
|
2332 * |
|
2333 * _.isEqual(words, otherWords, function(a, b) { |
|
2334 * var reGreet = /^(?:hello|hi)$/i, |
|
2335 * aGreet = _.isString(a) && reGreet.test(a), |
|
2336 * bGreet = _.isString(b) && reGreet.test(b); |
|
2337 * |
|
2338 * return (aGreet || bGreet) ? (aGreet == bGreet) : undefined; |
|
2339 * }); |
|
2340 * // => true |
|
2341 */ |
|
2342 function isEqual(a, b, callback, thisArg) { |
|
2343 return baseIsEqual(a, b, typeof callback == 'function' && baseCreateCallback(callback, thisArg, 2)); |
|
2344 } |
|
2345 |
|
2346 /** |
|
2347 * Checks if `value` is, or can be coerced to, a finite number. |
|
2348 * |
|
2349 * Note: This is not the same as native `isFinite` which will return true for |
|
2350 * booleans and empty strings. See http://es5.github.io/#x15.1.2.5. |
|
2351 * |
|
2352 * @static |
|
2353 * @memberOf _ |
|
2354 * @category Objects |
|
2355 * @param {*} value The value to check. |
|
2356 * @returns {boolean} Returns `true` if the `value` is finite, else `false`. |
|
2357 * @example |
|
2358 * |
|
2359 * _.isFinite(-101); |
|
2360 * // => true |
|
2361 * |
|
2362 * _.isFinite('10'); |
|
2363 * // => true |
|
2364 * |
|
2365 * _.isFinite(true); |
|
2366 * // => false |
|
2367 * |
|
2368 * _.isFinite(''); |
|
2369 * // => false |
|
2370 * |
|
2371 * _.isFinite(Infinity); |
|
2372 * // => false |
|
2373 */ |
|
2374 function isFinite(value) { |
|
2375 return nativeIsFinite(value) && !nativeIsNaN(parseFloat(value)); |
|
2376 } |
|
2377 |
|
2378 /** |
|
2379 * Checks if `value` is a function. |
|
2380 * |
|
2381 * @static |
|
2382 * @memberOf _ |
|
2383 * @category Objects |
|
2384 * @param {*} value The value to check. |
|
2385 * @returns {boolean} Returns `true` if the `value` is a function, else `false`. |
|
2386 * @example |
|
2387 * |
|
2388 * _.isFunction(_); |
|
2389 * // => true |
|
2390 */ |
|
2391 function isFunction(value) { |
|
2392 return typeof value == 'function'; |
|
2393 } |
|
2394 |
|
2395 /** |
|
2396 * Checks if `value` is the language type of Object. |
|
2397 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
|
2398 * |
|
2399 * @static |
|
2400 * @memberOf _ |
|
2401 * @category Objects |
|
2402 * @param {*} value The value to check. |
|
2403 * @returns {boolean} Returns `true` if the `value` is an object, else `false`. |
|
2404 * @example |
|
2405 * |
|
2406 * _.isObject({}); |
|
2407 * // => true |
|
2408 * |
|
2409 * _.isObject([1, 2, 3]); |
|
2410 * // => true |
|
2411 * |
|
2412 * _.isObject(1); |
|
2413 * // => false |
|
2414 */ |
|
2415 function isObject(value) { |
|
2416 // check if the value is the ECMAScript language type of Object |
|
2417 // http://es5.github.io/#x8 |
|
2418 // and avoid a V8 bug |
|
2419 // http://code.google.com/p/v8/issues/detail?id=2291 |
|
2420 return !!(value && objectTypes[typeof value]); |
|
2421 } |
|
2422 |
|
2423 /** |
|
2424 * Checks if `value` is `NaN`. |
|
2425 * |
|
2426 * Note: This is not the same as native `isNaN` which will return `true` for |
|
2427 * `undefined` and other non-numeric values. See http://es5.github.io/#x15.1.2.4. |
|
2428 * |
|
2429 * @static |
|
2430 * @memberOf _ |
|
2431 * @category Objects |
|
2432 * @param {*} value The value to check. |
|
2433 * @returns {boolean} Returns `true` if the `value` is `NaN`, else `false`. |
|
2434 * @example |
|
2435 * |
|
2436 * _.isNaN(NaN); |
|
2437 * // => true |
|
2438 * |
|
2439 * _.isNaN(new Number(NaN)); |
|
2440 * // => true |
|
2441 * |
|
2442 * isNaN(undefined); |
|
2443 * // => true |
|
2444 * |
|
2445 * _.isNaN(undefined); |
|
2446 * // => false |
|
2447 */ |
|
2448 function isNaN(value) { |
|
2449 // `NaN` as a primitive is the only value that is not equal to itself |
|
2450 // (perform the [[Class]] check first to avoid errors with some host objects in IE) |
|
2451 return isNumber(value) && value != +value; |
|
2452 } |
|
2453 |
|
2454 /** |
|
2455 * Checks if `value` is `null`. |
|
2456 * |
|
2457 * @static |
|
2458 * @memberOf _ |
|
2459 * @category Objects |
|
2460 * @param {*} value The value to check. |
|
2461 * @returns {boolean} Returns `true` if the `value` is `null`, else `false`. |
|
2462 * @example |
|
2463 * |
|
2464 * _.isNull(null); |
|
2465 * // => true |
|
2466 * |
|
2467 * _.isNull(undefined); |
|
2468 * // => false |
|
2469 */ |
|
2470 function isNull(value) { |
|
2471 return value === null; |
|
2472 } |
|
2473 |
|
2474 /** |
|
2475 * Checks if `value` is a number. |
|
2476 * |
|
2477 * Note: `NaN` is considered a number. See http://es5.github.io/#x8.5. |
|
2478 * |
|
2479 * @static |
|
2480 * @memberOf _ |
|
2481 * @category Objects |
|
2482 * @param {*} value The value to check. |
|
2483 * @returns {boolean} Returns `true` if the `value` is a number, else `false`. |
|
2484 * @example |
|
2485 * |
|
2486 * _.isNumber(8.4 * 5); |
|
2487 * // => true |
|
2488 */ |
|
2489 function isNumber(value) { |
|
2490 return typeof value == 'number' || |
|
2491 value && typeof value == 'object' && toString.call(value) == numberClass || false; |
|
2492 } |
|
2493 |
|
2494 /** |
|
2495 * Checks if `value` is an object created by the `Object` constructor. |
|
2496 * |
|
2497 * @static |
|
2498 * @memberOf _ |
|
2499 * @category Objects |
|
2500 * @param {*} value The value to check. |
|
2501 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
|
2502 * @example |
|
2503 * |
|
2504 * function Shape() { |
|
2505 * this.x = 0; |
|
2506 * this.y = 0; |
|
2507 * } |
|
2508 * |
|
2509 * _.isPlainObject(new Shape); |
|
2510 * // => false |
|
2511 * |
|
2512 * _.isPlainObject([1, 2, 3]); |
|
2513 * // => false |
|
2514 * |
|
2515 * _.isPlainObject({ 'x': 0, 'y': 0 }); |
|
2516 * // => true |
|
2517 */ |
|
2518 var isPlainObject = !getPrototypeOf ? shimIsPlainObject : function(value) { |
|
2519 if (!(value && toString.call(value) == objectClass)) { |
|
2520 return false; |
|
2521 } |
|
2522 var valueOf = value.valueOf, |
|
2523 objProto = isNative(valueOf) && (objProto = getPrototypeOf(valueOf)) && getPrototypeOf(objProto); |
|
2524 |
|
2525 return objProto |
|
2526 ? (value == objProto || getPrototypeOf(value) == objProto) |
|
2527 : shimIsPlainObject(value); |
|
2528 }; |
|
2529 |
|
2530 /** |
|
2531 * Checks if `value` is a regular expression. |
|
2532 * |
|
2533 * @static |
|
2534 * @memberOf _ |
|
2535 * @category Objects |
|
2536 * @param {*} value The value to check. |
|
2537 * @returns {boolean} Returns `true` if the `value` is a regular expression, else `false`. |
|
2538 * @example |
|
2539 * |
|
2540 * _.isRegExp(/fred/); |
|
2541 * // => true |
|
2542 */ |
|
2543 function isRegExp(value) { |
|
2544 return value && typeof value == 'object' && toString.call(value) == regexpClass || false; |
|
2545 } |
|
2546 |
|
2547 /** |
|
2548 * Checks if `value` is a string. |
|
2549 * |
|
2550 * @static |
|
2551 * @memberOf _ |
|
2552 * @category Objects |
|
2553 * @param {*} value The value to check. |
|
2554 * @returns {boolean} Returns `true` if the `value` is a string, else `false`. |
|
2555 * @example |
|
2556 * |
|
2557 * _.isString('fred'); |
|
2558 * // => true |
|
2559 */ |
|
2560 function isString(value) { |
|
2561 return typeof value == 'string' || |
|
2562 value && typeof value == 'object' && toString.call(value) == stringClass || false; |
|
2563 } |
|
2564 |
|
2565 /** |
|
2566 * Checks if `value` is `undefined`. |
|
2567 * |
|
2568 * @static |
|
2569 * @memberOf _ |
|
2570 * @category Objects |
|
2571 * @param {*} value The value to check. |
|
2572 * @returns {boolean} Returns `true` if the `value` is `undefined`, else `false`. |
|
2573 * @example |
|
2574 * |
|
2575 * _.isUndefined(void 0); |
|
2576 * // => true |
|
2577 */ |
|
2578 function isUndefined(value) { |
|
2579 return typeof value == 'undefined'; |
|
2580 } |
|
2581 |
|
2582 /** |
|
2583 * Creates an object with the same keys as `object` and values generated by |
|
2584 * running each own enumerable property of `object` through the callback. |
|
2585 * The callback is bound to `thisArg` and invoked with three arguments; |
|
2586 * (value, key, object). |
|
2587 * |
|
2588 * If a property name is provided for `callback` the created "_.pluck" style |
|
2589 * callback will return the property value of the given element. |
|
2590 * |
|
2591 * If an object is provided for `callback` the created "_.where" style callback |
|
2592 * will return `true` for elements that have the properties of the given object, |
|
2593 * else `false`. |
|
2594 * |
|
2595 * @static |
|
2596 * @memberOf _ |
|
2597 * @category Objects |
|
2598 * @param {Object} object The object to iterate over. |
|
2599 * @param {Function|Object|string} [callback=identity] The function called |
|
2600 * per iteration. If a property name or object is provided it will be used |
|
2601 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
2602 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2603 * @returns {Array} Returns a new object with values of the results of each `callback` execution. |
|
2604 * @example |
|
2605 * |
|
2606 * _.mapValues({ 'a': 1, 'b': 2, 'c': 3} , function(num) { return num * 3; }); |
|
2607 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
2608 * |
|
2609 * var characters = { |
|
2610 * 'fred': { 'name': 'fred', 'age': 40 }, |
|
2611 * 'pebbles': { 'name': 'pebbles', 'age': 1 } |
|
2612 * }; |
|
2613 * |
|
2614 * // using "_.pluck" callback shorthand |
|
2615 * _.mapValues(characters, 'age'); |
|
2616 * // => { 'fred': 40, 'pebbles': 1 } |
|
2617 */ |
|
2618 function mapValues(object, callback, thisArg) { |
|
2619 var result = {}; |
|
2620 callback = lodash.createCallback(callback, thisArg, 3); |
|
2621 |
|
2622 forOwn(object, function(value, key, object) { |
|
2623 result[key] = callback(value, key, object); |
|
2624 }); |
|
2625 return result; |
|
2626 } |
|
2627 |
|
2628 /** |
|
2629 * Recursively merges own enumerable properties of the source object(s), that |
|
2630 * don't resolve to `undefined` into the destination object. Subsequent sources |
|
2631 * will overwrite property assignments of previous sources. If a callback is |
|
2632 * provided it will be executed to produce the merged values of the destination |
|
2633 * and source properties. If the callback returns `undefined` merging will |
|
2634 * be handled by the method instead. The callback is bound to `thisArg` and |
|
2635 * invoked with two arguments; (objectValue, sourceValue). |
|
2636 * |
|
2637 * @static |
|
2638 * @memberOf _ |
|
2639 * @category Objects |
|
2640 * @param {Object} object The destination object. |
|
2641 * @param {...Object} [source] The source objects. |
|
2642 * @param {Function} [callback] The function to customize merging properties. |
|
2643 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2644 * @returns {Object} Returns the destination object. |
|
2645 * @example |
|
2646 * |
|
2647 * var names = { |
|
2648 * 'characters': [ |
|
2649 * { 'name': 'barney' }, |
|
2650 * { 'name': 'fred' } |
|
2651 * ] |
|
2652 * }; |
|
2653 * |
|
2654 * var ages = { |
|
2655 * 'characters': [ |
|
2656 * { 'age': 36 }, |
|
2657 * { 'age': 40 } |
|
2658 * ] |
|
2659 * }; |
|
2660 * |
|
2661 * _.merge(names, ages); |
|
2662 * // => { 'characters': [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] } |
|
2663 * |
|
2664 * var food = { |
|
2665 * 'fruits': ['apple'], |
|
2666 * 'vegetables': ['beet'] |
|
2667 * }; |
|
2668 * |
|
2669 * var otherFood = { |
|
2670 * 'fruits': ['banana'], |
|
2671 * 'vegetables': ['carrot'] |
|
2672 * }; |
|
2673 * |
|
2674 * _.merge(food, otherFood, function(a, b) { |
|
2675 * return _.isArray(a) ? a.concat(b) : undefined; |
|
2676 * }); |
|
2677 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot] } |
|
2678 */ |
|
2679 function merge(object) { |
|
2680 var args = arguments, |
|
2681 length = 2; |
|
2682 |
|
2683 if (!isObject(object)) { |
|
2684 return object; |
|
2685 } |
|
2686 // allows working with `_.reduce` and `_.reduceRight` without using |
|
2687 // their `index` and `collection` arguments |
|
2688 if (typeof args[2] != 'number') { |
|
2689 length = args.length; |
|
2690 } |
|
2691 if (length > 3 && typeof args[length - 2] == 'function') { |
|
2692 var callback = baseCreateCallback(args[--length - 1], args[length--], 2); |
|
2693 } else if (length > 2 && typeof args[length - 1] == 'function') { |
|
2694 callback = args[--length]; |
|
2695 } |
|
2696 var sources = slice(arguments, 1, length), |
|
2697 index = -1, |
|
2698 stackA = getArray(), |
|
2699 stackB = getArray(); |
|
2700 |
|
2701 while (++index < length) { |
|
2702 baseMerge(object, sources[index], callback, stackA, stackB); |
|
2703 } |
|
2704 releaseArray(stackA); |
|
2705 releaseArray(stackB); |
|
2706 return object; |
|
2707 } |
|
2708 |
|
2709 /** |
|
2710 * Creates a shallow clone of `object` excluding the specified properties. |
|
2711 * Property names may be specified as individual arguments or as arrays of |
|
2712 * property names. If a callback is provided it will be executed for each |
|
2713 * property of `object` omitting the properties the callback returns truey |
|
2714 * for. The callback is bound to `thisArg` and invoked with three arguments; |
|
2715 * (value, key, object). |
|
2716 * |
|
2717 * @static |
|
2718 * @memberOf _ |
|
2719 * @category Objects |
|
2720 * @param {Object} object The source object. |
|
2721 * @param {Function|...string|string[]} [callback] The properties to omit or the |
|
2722 * function called per iteration. |
|
2723 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2724 * @returns {Object} Returns an object without the omitted properties. |
|
2725 * @example |
|
2726 * |
|
2727 * _.omit({ 'name': 'fred', 'age': 40 }, 'age'); |
|
2728 * // => { 'name': 'fred' } |
|
2729 * |
|
2730 * _.omit({ 'name': 'fred', 'age': 40 }, function(value) { |
|
2731 * return typeof value == 'number'; |
|
2732 * }); |
|
2733 * // => { 'name': 'fred' } |
|
2734 */ |
|
2735 function omit(object, callback, thisArg) { |
|
2736 var result = {}; |
|
2737 if (typeof callback != 'function') { |
|
2738 var props = []; |
|
2739 forIn(object, function(value, key) { |
|
2740 props.push(key); |
|
2741 }); |
|
2742 props = baseDifference(props, baseFlatten(arguments, true, false, 1)); |
|
2743 |
|
2744 var index = -1, |
|
2745 length = props.length; |
|
2746 |
|
2747 while (++index < length) { |
|
2748 var key = props[index]; |
|
2749 result[key] = object[key]; |
|
2750 } |
|
2751 } else { |
|
2752 callback = lodash.createCallback(callback, thisArg, 3); |
|
2753 forIn(object, function(value, key, object) { |
|
2754 if (!callback(value, key, object)) { |
|
2755 result[key] = value; |
|
2756 } |
|
2757 }); |
|
2758 } |
|
2759 return result; |
|
2760 } |
|
2761 |
|
2762 /** |
|
2763 * Creates a two dimensional array of an object's key-value pairs, |
|
2764 * i.e. `[[key1, value1], [key2, value2]]`. |
|
2765 * |
|
2766 * @static |
|
2767 * @memberOf _ |
|
2768 * @category Objects |
|
2769 * @param {Object} object The object to inspect. |
|
2770 * @returns {Array} Returns new array of key-value pairs. |
|
2771 * @example |
|
2772 * |
|
2773 * _.pairs({ 'barney': 36, 'fred': 40 }); |
|
2774 * // => [['barney', 36], ['fred', 40]] (property order is not guaranteed across environments) |
|
2775 */ |
|
2776 function pairs(object) { |
|
2777 var index = -1, |
|
2778 props = keys(object), |
|
2779 length = props.length, |
|
2780 result = Array(length); |
|
2781 |
|
2782 while (++index < length) { |
|
2783 var key = props[index]; |
|
2784 result[index] = [key, object[key]]; |
|
2785 } |
|
2786 return result; |
|
2787 } |
|
2788 |
|
2789 /** |
|
2790 * Creates a shallow clone of `object` composed of the specified properties. |
|
2791 * Property names may be specified as individual arguments or as arrays of |
|
2792 * property names. If a callback is provided it will be executed for each |
|
2793 * property of `object` picking the properties the callback returns truey |
|
2794 * for. The callback is bound to `thisArg` and invoked with three arguments; |
|
2795 * (value, key, object). |
|
2796 * |
|
2797 * @static |
|
2798 * @memberOf _ |
|
2799 * @category Objects |
|
2800 * @param {Object} object The source object. |
|
2801 * @param {Function|...string|string[]} [callback] The function called per |
|
2802 * iteration or property names to pick, specified as individual property |
|
2803 * names or arrays of property names. |
|
2804 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2805 * @returns {Object} Returns an object composed of the picked properties. |
|
2806 * @example |
|
2807 * |
|
2808 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, 'name'); |
|
2809 * // => { 'name': 'fred' } |
|
2810 * |
|
2811 * _.pick({ 'name': 'fred', '_userid': 'fred1' }, function(value, key) { |
|
2812 * return key.charAt(0) != '_'; |
|
2813 * }); |
|
2814 * // => { 'name': 'fred' } |
|
2815 */ |
|
2816 function pick(object, callback, thisArg) { |
|
2817 var result = {}; |
|
2818 if (typeof callback != 'function') { |
|
2819 var index = -1, |
|
2820 props = baseFlatten(arguments, true, false, 1), |
|
2821 length = isObject(object) ? props.length : 0; |
|
2822 |
|
2823 while (++index < length) { |
|
2824 var key = props[index]; |
|
2825 if (key in object) { |
|
2826 result[key] = object[key]; |
|
2827 } |
|
2828 } |
|
2829 } else { |
|
2830 callback = lodash.createCallback(callback, thisArg, 3); |
|
2831 forIn(object, function(value, key, object) { |
|
2832 if (callback(value, key, object)) { |
|
2833 result[key] = value; |
|
2834 } |
|
2835 }); |
|
2836 } |
|
2837 return result; |
|
2838 } |
|
2839 |
|
2840 /** |
|
2841 * An alternative to `_.reduce` this method transforms `object` to a new |
|
2842 * `accumulator` object which is the result of running each of its own |
|
2843 * enumerable properties through a callback, with each callback execution |
|
2844 * potentially mutating the `accumulator` object. The callback is bound to |
|
2845 * `thisArg` and invoked with four arguments; (accumulator, value, key, object). |
|
2846 * Callbacks may exit iteration early by explicitly returning `false`. |
|
2847 * |
|
2848 * @static |
|
2849 * @memberOf _ |
|
2850 * @category Objects |
|
2851 * @param {Array|Object} object The object to iterate over. |
|
2852 * @param {Function} [callback=identity] The function called per iteration. |
|
2853 * @param {*} [accumulator] The custom accumulator value. |
|
2854 * @param {*} [thisArg] The `this` binding of `callback`. |
|
2855 * @returns {*} Returns the accumulated value. |
|
2856 * @example |
|
2857 * |
|
2858 * var squares = _.transform([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], function(result, num) { |
|
2859 * num *= num; |
|
2860 * if (num % 2) { |
|
2861 * return result.push(num) < 3; |
|
2862 * } |
|
2863 * }); |
|
2864 * // => [1, 9, 25] |
|
2865 * |
|
2866 * var mapped = _.transform({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { |
|
2867 * result[key] = num * 3; |
|
2868 * }); |
|
2869 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
2870 */ |
|
2871 function transform(object, callback, accumulator, thisArg) { |
|
2872 var isArr = isArray(object); |
|
2873 if (accumulator == null) { |
|
2874 if (isArr) { |
|
2875 accumulator = []; |
|
2876 } else { |
|
2877 var ctor = object && object.constructor, |
|
2878 proto = ctor && ctor.prototype; |
|
2879 |
|
2880 accumulator = baseCreate(proto); |
|
2881 } |
|
2882 } |
|
2883 if (callback) { |
|
2884 callback = lodash.createCallback(callback, thisArg, 4); |
|
2885 (isArr ? forEach : forOwn)(object, function(value, index, object) { |
|
2886 return callback(accumulator, value, index, object); |
|
2887 }); |
|
2888 } |
|
2889 return accumulator; |
|
2890 } |
|
2891 |
|
2892 /** |
|
2893 * Creates an array composed of the own enumerable property values of `object`. |
|
2894 * |
|
2895 * @static |
|
2896 * @memberOf _ |
|
2897 * @category Objects |
|
2898 * @param {Object} object The object to inspect. |
|
2899 * @returns {Array} Returns an array of property values. |
|
2900 * @example |
|
2901 * |
|
2902 * _.values({ 'one': 1, 'two': 2, 'three': 3 }); |
|
2903 * // => [1, 2, 3] (property order is not guaranteed across environments) |
|
2904 */ |
|
2905 function values(object) { |
|
2906 var index = -1, |
|
2907 props = keys(object), |
|
2908 length = props.length, |
|
2909 result = Array(length); |
|
2910 |
|
2911 while (++index < length) { |
|
2912 result[index] = object[props[index]]; |
|
2913 } |
|
2914 return result; |
|
2915 } |
|
2916 |
|
2917 /*--------------------------------------------------------------------------*/ |
|
2918 |
|
2919 /** |
|
2920 * Creates an array of elements from the specified indexes, or keys, of the |
|
2921 * `collection`. Indexes may be specified as individual arguments or as arrays |
|
2922 * of indexes. |
|
2923 * |
|
2924 * @static |
|
2925 * @memberOf _ |
|
2926 * @category Collections |
|
2927 * @param {Array|Object|string} collection The collection to iterate over. |
|
2928 * @param {...(number|number[]|string|string[])} [index] The indexes of `collection` |
|
2929 * to retrieve, specified as individual indexes or arrays of indexes. |
|
2930 * @returns {Array} Returns a new array of elements corresponding to the |
|
2931 * provided indexes. |
|
2932 * @example |
|
2933 * |
|
2934 * _.at(['a', 'b', 'c', 'd', 'e'], [0, 2, 4]); |
|
2935 * // => ['a', 'c', 'e'] |
|
2936 * |
|
2937 * _.at(['fred', 'barney', 'pebbles'], 0, 2); |
|
2938 * // => ['fred', 'pebbles'] |
|
2939 */ |
|
2940 function at(collection) { |
|
2941 var args = arguments, |
|
2942 index = -1, |
|
2943 props = baseFlatten(args, true, false, 1), |
|
2944 length = (args[2] && args[2][args[1]] === collection) ? 1 : props.length, |
|
2945 result = Array(length); |
|
2946 |
|
2947 while(++index < length) { |
|
2948 result[index] = collection[props[index]]; |
|
2949 } |
|
2950 return result; |
|
2951 } |
|
2952 |
|
2953 /** |
|
2954 * Checks if a given value is present in a collection using strict equality |
|
2955 * for comparisons, i.e. `===`. If `fromIndex` is negative, it is used as the |
|
2956 * offset from the end of the collection. |
|
2957 * |
|
2958 * @static |
|
2959 * @memberOf _ |
|
2960 * @alias include |
|
2961 * @category Collections |
|
2962 * @param {Array|Object|string} collection The collection to iterate over. |
|
2963 * @param {*} target The value to check for. |
|
2964 * @param {number} [fromIndex=0] The index to search from. |
|
2965 * @returns {boolean} Returns `true` if the `target` element is found, else `false`. |
|
2966 * @example |
|
2967 * |
|
2968 * _.contains([1, 2, 3], 1); |
|
2969 * // => true |
|
2970 * |
|
2971 * _.contains([1, 2, 3], 1, 2); |
|
2972 * // => false |
|
2973 * |
|
2974 * _.contains({ 'name': 'fred', 'age': 40 }, 'fred'); |
|
2975 * // => true |
|
2976 * |
|
2977 * _.contains('pebbles', 'eb'); |
|
2978 * // => true |
|
2979 */ |
|
2980 function contains(collection, target, fromIndex) { |
|
2981 var index = -1, |
|
2982 indexOf = getIndexOf(), |
|
2983 length = collection ? collection.length : 0, |
|
2984 result = false; |
|
2985 |
|
2986 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex) || 0; |
|
2987 if (isArray(collection)) { |
|
2988 result = indexOf(collection, target, fromIndex) > -1; |
|
2989 } else if (typeof length == 'number') { |
|
2990 result = (isString(collection) ? collection.indexOf(target, fromIndex) : indexOf(collection, target, fromIndex)) > -1; |
|
2991 } else { |
|
2992 forOwn(collection, function(value) { |
|
2993 if (++index >= fromIndex) { |
|
2994 return !(result = value === target); |
|
2995 } |
|
2996 }); |
|
2997 } |
|
2998 return result; |
|
2999 } |
|
3000 |
|
3001 /** |
|
3002 * Creates an object composed of keys generated from the results of running |
|
3003 * each element of `collection` through the callback. The corresponding value |
|
3004 * of each key is the number of times the key was returned by the callback. |
|
3005 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3006 * (value, index|key, collection). |
|
3007 * |
|
3008 * If a property name is provided for `callback` the created "_.pluck" style |
|
3009 * callback will return the property value of the given element. |
|
3010 * |
|
3011 * If an object is provided for `callback` the created "_.where" style callback |
|
3012 * will return `true` for elements that have the properties of the given object, |
|
3013 * else `false`. |
|
3014 * |
|
3015 * @static |
|
3016 * @memberOf _ |
|
3017 * @category Collections |
|
3018 * @param {Array|Object|string} collection The collection to iterate over. |
|
3019 * @param {Function|Object|string} [callback=identity] The function called |
|
3020 * per iteration. If a property name or object is provided it will be used |
|
3021 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3022 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3023 * @returns {Object} Returns the composed aggregate object. |
|
3024 * @example |
|
3025 * |
|
3026 * _.countBy([4.3, 6.1, 6.4], function(num) { return Math.floor(num); }); |
|
3027 * // => { '4': 1, '6': 2 } |
|
3028 * |
|
3029 * _.countBy([4.3, 6.1, 6.4], function(num) { return this.floor(num); }, Math); |
|
3030 * // => { '4': 1, '6': 2 } |
|
3031 * |
|
3032 * _.countBy(['one', 'two', 'three'], 'length'); |
|
3033 * // => { '3': 2, '5': 1 } |
|
3034 */ |
|
3035 var countBy = createAggregator(function(result, value, key) { |
|
3036 (hasOwnProperty.call(result, key) ? result[key]++ : result[key] = 1); |
|
3037 }); |
|
3038 |
|
3039 /** |
|
3040 * Checks if the given callback returns truey value for **all** elements of |
|
3041 * a collection. The callback is bound to `thisArg` and invoked with three |
|
3042 * arguments; (value, index|key, collection). |
|
3043 * |
|
3044 * If a property name is provided for `callback` the created "_.pluck" style |
|
3045 * callback will return the property value of the given element. |
|
3046 * |
|
3047 * If an object is provided for `callback` the created "_.where" style callback |
|
3048 * will return `true` for elements that have the properties of the given object, |
|
3049 * else `false`. |
|
3050 * |
|
3051 * @static |
|
3052 * @memberOf _ |
|
3053 * @alias all |
|
3054 * @category Collections |
|
3055 * @param {Array|Object|string} collection The collection to iterate over. |
|
3056 * @param {Function|Object|string} [callback=identity] The function called |
|
3057 * per iteration. If a property name or object is provided it will be used |
|
3058 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3059 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3060 * @returns {boolean} Returns `true` if all elements passed the callback check, |
|
3061 * else `false`. |
|
3062 * @example |
|
3063 * |
|
3064 * _.every([true, 1, null, 'yes']); |
|
3065 * // => false |
|
3066 * |
|
3067 * var characters = [ |
|
3068 * { 'name': 'barney', 'age': 36 }, |
|
3069 * { 'name': 'fred', 'age': 40 } |
|
3070 * ]; |
|
3071 * |
|
3072 * // using "_.pluck" callback shorthand |
|
3073 * _.every(characters, 'age'); |
|
3074 * // => true |
|
3075 * |
|
3076 * // using "_.where" callback shorthand |
|
3077 * _.every(characters, { 'age': 36 }); |
|
3078 * // => false |
|
3079 */ |
|
3080 function every(collection, callback, thisArg) { |
|
3081 var result = true; |
|
3082 callback = lodash.createCallback(callback, thisArg, 3); |
|
3083 |
|
3084 var index = -1, |
|
3085 length = collection ? collection.length : 0; |
|
3086 |
|
3087 if (typeof length == 'number') { |
|
3088 while (++index < length) { |
|
3089 if (!(result = !!callback(collection[index], index, collection))) { |
|
3090 break; |
|
3091 } |
|
3092 } |
|
3093 } else { |
|
3094 forOwn(collection, function(value, index, collection) { |
|
3095 return (result = !!callback(value, index, collection)); |
|
3096 }); |
|
3097 } |
|
3098 return result; |
|
3099 } |
|
3100 |
|
3101 /** |
|
3102 * Iterates over elements of a collection, returning an array of all elements |
|
3103 * the callback returns truey for. The callback is bound to `thisArg` and |
|
3104 * invoked with three arguments; (value, index|key, collection). |
|
3105 * |
|
3106 * If a property name is provided for `callback` the created "_.pluck" style |
|
3107 * callback will return the property value of the given element. |
|
3108 * |
|
3109 * If an object is provided for `callback` the created "_.where" style callback |
|
3110 * will return `true` for elements that have the properties of the given object, |
|
3111 * else `false`. |
|
3112 * |
|
3113 * @static |
|
3114 * @memberOf _ |
|
3115 * @alias select |
|
3116 * @category Collections |
|
3117 * @param {Array|Object|string} collection The collection to iterate over. |
|
3118 * @param {Function|Object|string} [callback=identity] The function called |
|
3119 * per iteration. If a property name or object is provided it will be used |
|
3120 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3121 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3122 * @returns {Array} Returns a new array of elements that passed the callback check. |
|
3123 * @example |
|
3124 * |
|
3125 * var evens = _.filter([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); |
|
3126 * // => [2, 4, 6] |
|
3127 * |
|
3128 * var characters = [ |
|
3129 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3130 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3131 * ]; |
|
3132 * |
|
3133 * // using "_.pluck" callback shorthand |
|
3134 * _.filter(characters, 'blocked'); |
|
3135 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] |
|
3136 * |
|
3137 * // using "_.where" callback shorthand |
|
3138 * _.filter(characters, { 'age': 36 }); |
|
3139 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] |
|
3140 */ |
|
3141 function filter(collection, callback, thisArg) { |
|
3142 var result = []; |
|
3143 callback = lodash.createCallback(callback, thisArg, 3); |
|
3144 |
|
3145 var index = -1, |
|
3146 length = collection ? collection.length : 0; |
|
3147 |
|
3148 if (typeof length == 'number') { |
|
3149 while (++index < length) { |
|
3150 var value = collection[index]; |
|
3151 if (callback(value, index, collection)) { |
|
3152 result.push(value); |
|
3153 } |
|
3154 } |
|
3155 } else { |
|
3156 forOwn(collection, function(value, index, collection) { |
|
3157 if (callback(value, index, collection)) { |
|
3158 result.push(value); |
|
3159 } |
|
3160 }); |
|
3161 } |
|
3162 return result; |
|
3163 } |
|
3164 |
|
3165 /** |
|
3166 * Iterates over elements of a collection, returning the first element that |
|
3167 * the callback returns truey for. The callback is bound to `thisArg` and |
|
3168 * invoked with three arguments; (value, index|key, collection). |
|
3169 * |
|
3170 * If a property name is provided for `callback` the created "_.pluck" style |
|
3171 * callback will return the property value of the given element. |
|
3172 * |
|
3173 * If an object is provided for `callback` the created "_.where" style callback |
|
3174 * will return `true` for elements that have the properties of the given object, |
|
3175 * else `false`. |
|
3176 * |
|
3177 * @static |
|
3178 * @memberOf _ |
|
3179 * @alias detect, findWhere |
|
3180 * @category Collections |
|
3181 * @param {Array|Object|string} collection The collection to iterate over. |
|
3182 * @param {Function|Object|string} [callback=identity] The function called |
|
3183 * per iteration. If a property name or object is provided it will be used |
|
3184 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3185 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3186 * @returns {*} Returns the found element, else `undefined`. |
|
3187 * @example |
|
3188 * |
|
3189 * var characters = [ |
|
3190 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3191 * { 'name': 'fred', 'age': 40, 'blocked': true }, |
|
3192 * { 'name': 'pebbles', 'age': 1, 'blocked': false } |
|
3193 * ]; |
|
3194 * |
|
3195 * _.find(characters, function(chr) { |
|
3196 * return chr.age < 40; |
|
3197 * }); |
|
3198 * // => { 'name': 'barney', 'age': 36, 'blocked': false } |
|
3199 * |
|
3200 * // using "_.where" callback shorthand |
|
3201 * _.find(characters, { 'age': 1 }); |
|
3202 * // => { 'name': 'pebbles', 'age': 1, 'blocked': false } |
|
3203 * |
|
3204 * // using "_.pluck" callback shorthand |
|
3205 * _.find(characters, 'blocked'); |
|
3206 * // => { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3207 */ |
|
3208 function find(collection, callback, thisArg) { |
|
3209 callback = lodash.createCallback(callback, thisArg, 3); |
|
3210 |
|
3211 var index = -1, |
|
3212 length = collection ? collection.length : 0; |
|
3213 |
|
3214 if (typeof length == 'number') { |
|
3215 while (++index < length) { |
|
3216 var value = collection[index]; |
|
3217 if (callback(value, index, collection)) { |
|
3218 return value; |
|
3219 } |
|
3220 } |
|
3221 } else { |
|
3222 var result; |
|
3223 forOwn(collection, function(value, index, collection) { |
|
3224 if (callback(value, index, collection)) { |
|
3225 result = value; |
|
3226 return false; |
|
3227 } |
|
3228 }); |
|
3229 return result; |
|
3230 } |
|
3231 } |
|
3232 |
|
3233 /** |
|
3234 * This method is like `_.find` except that it iterates over elements |
|
3235 * of a `collection` from right to left. |
|
3236 * |
|
3237 * @static |
|
3238 * @memberOf _ |
|
3239 * @category Collections |
|
3240 * @param {Array|Object|string} collection The collection to iterate over. |
|
3241 * @param {Function|Object|string} [callback=identity] The function called |
|
3242 * per iteration. If a property name or object is provided it will be used |
|
3243 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3244 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3245 * @returns {*} Returns the found element, else `undefined`. |
|
3246 * @example |
|
3247 * |
|
3248 * _.findLast([1, 2, 3, 4], function(num) { |
|
3249 * return num % 2 == 1; |
|
3250 * }); |
|
3251 * // => 3 |
|
3252 */ |
|
3253 function findLast(collection, callback, thisArg) { |
|
3254 var result; |
|
3255 callback = lodash.createCallback(callback, thisArg, 3); |
|
3256 forEachRight(collection, function(value, index, collection) { |
|
3257 if (callback(value, index, collection)) { |
|
3258 result = value; |
|
3259 return false; |
|
3260 } |
|
3261 }); |
|
3262 return result; |
|
3263 } |
|
3264 |
|
3265 /** |
|
3266 * Iterates over elements of a collection, executing the callback for each |
|
3267 * element. The callback is bound to `thisArg` and invoked with three arguments; |
|
3268 * (value, index|key, collection). Callbacks may exit iteration early by |
|
3269 * explicitly returning `false`. |
|
3270 * |
|
3271 * Note: As with other "Collections" methods, objects with a `length` property |
|
3272 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
|
3273 * may be used for object iteration. |
|
3274 * |
|
3275 * @static |
|
3276 * @memberOf _ |
|
3277 * @alias each |
|
3278 * @category Collections |
|
3279 * @param {Array|Object|string} collection The collection to iterate over. |
|
3280 * @param {Function} [callback=identity] The function called per iteration. |
|
3281 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3282 * @returns {Array|Object|string} Returns `collection`. |
|
3283 * @example |
|
3284 * |
|
3285 * _([1, 2, 3]).forEach(function(num) { console.log(num); }).join(','); |
|
3286 * // => logs each number and returns '1,2,3' |
|
3287 * |
|
3288 * _.forEach({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { console.log(num); }); |
|
3289 * // => logs each number and returns the object (property order is not guaranteed across environments) |
|
3290 */ |
|
3291 function forEach(collection, callback, thisArg) { |
|
3292 var index = -1, |
|
3293 length = collection ? collection.length : 0; |
|
3294 |
|
3295 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
3296 if (typeof length == 'number') { |
|
3297 while (++index < length) { |
|
3298 if (callback(collection[index], index, collection) === false) { |
|
3299 break; |
|
3300 } |
|
3301 } |
|
3302 } else { |
|
3303 forOwn(collection, callback); |
|
3304 } |
|
3305 return collection; |
|
3306 } |
|
3307 |
|
3308 /** |
|
3309 * This method is like `_.forEach` except that it iterates over elements |
|
3310 * of a `collection` from right to left. |
|
3311 * |
|
3312 * @static |
|
3313 * @memberOf _ |
|
3314 * @alias eachRight |
|
3315 * @category Collections |
|
3316 * @param {Array|Object|string} collection The collection to iterate over. |
|
3317 * @param {Function} [callback=identity] The function called per iteration. |
|
3318 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3319 * @returns {Array|Object|string} Returns `collection`. |
|
3320 * @example |
|
3321 * |
|
3322 * _([1, 2, 3]).forEachRight(function(num) { console.log(num); }).join(','); |
|
3323 * // => logs each number from right to left and returns '3,2,1' |
|
3324 */ |
|
3325 function forEachRight(collection, callback, thisArg) { |
|
3326 var length = collection ? collection.length : 0; |
|
3327 callback = callback && typeof thisArg == 'undefined' ? callback : baseCreateCallback(callback, thisArg, 3); |
|
3328 if (typeof length == 'number') { |
|
3329 while (length--) { |
|
3330 if (callback(collection[length], length, collection) === false) { |
|
3331 break; |
|
3332 } |
|
3333 } |
|
3334 } else { |
|
3335 var props = keys(collection); |
|
3336 length = props.length; |
|
3337 forOwn(collection, function(value, key, collection) { |
|
3338 key = props ? props[--length] : --length; |
|
3339 return callback(collection[key], key, collection); |
|
3340 }); |
|
3341 } |
|
3342 return collection; |
|
3343 } |
|
3344 |
|
3345 /** |
|
3346 * Creates an object composed of keys generated from the results of running |
|
3347 * each element of a collection through the callback. The corresponding value |
|
3348 * of each key is an array of the elements responsible for generating the key. |
|
3349 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3350 * (value, index|key, collection). |
|
3351 * |
|
3352 * If a property name is provided for `callback` the created "_.pluck" style |
|
3353 * callback will return the property value of the given element. |
|
3354 * |
|
3355 * If an object is provided for `callback` the created "_.where" style callback |
|
3356 * will return `true` for elements that have the properties of the given object, |
|
3357 * else `false` |
|
3358 * |
|
3359 * @static |
|
3360 * @memberOf _ |
|
3361 * @category Collections |
|
3362 * @param {Array|Object|string} collection The collection to iterate over. |
|
3363 * @param {Function|Object|string} [callback=identity] The function called |
|
3364 * per iteration. If a property name or object is provided it will be used |
|
3365 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3366 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3367 * @returns {Object} Returns the composed aggregate object. |
|
3368 * @example |
|
3369 * |
|
3370 * _.groupBy([4.2, 6.1, 6.4], function(num) { return Math.floor(num); }); |
|
3371 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
3372 * |
|
3373 * _.groupBy([4.2, 6.1, 6.4], function(num) { return this.floor(num); }, Math); |
|
3374 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
3375 * |
|
3376 * // using "_.pluck" callback shorthand |
|
3377 * _.groupBy(['one', 'two', 'three'], 'length'); |
|
3378 * // => { '3': ['one', 'two'], '5': ['three'] } |
|
3379 */ |
|
3380 var groupBy = createAggregator(function(result, value, key) { |
|
3381 (hasOwnProperty.call(result, key) ? result[key] : result[key] = []).push(value); |
|
3382 }); |
|
3383 |
|
3384 /** |
|
3385 * Creates an object composed of keys generated from the results of running |
|
3386 * each element of the collection through the given callback. The corresponding |
|
3387 * value of each key is the last element responsible for generating the key. |
|
3388 * The callback is bound to `thisArg` and invoked with three arguments; |
|
3389 * (value, index|key, collection). |
|
3390 * |
|
3391 * If a property name is provided for `callback` the created "_.pluck" style |
|
3392 * callback will return the property value of the given element. |
|
3393 * |
|
3394 * If an object is provided for `callback` the created "_.where" style callback |
|
3395 * will return `true` for elements that have the properties of the given object, |
|
3396 * else `false`. |
|
3397 * |
|
3398 * @static |
|
3399 * @memberOf _ |
|
3400 * @category Collections |
|
3401 * @param {Array|Object|string} collection The collection to iterate over. |
|
3402 * @param {Function|Object|string} [callback=identity] The function called |
|
3403 * per iteration. If a property name or object is provided it will be used |
|
3404 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3405 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3406 * @returns {Object} Returns the composed aggregate object. |
|
3407 * @example |
|
3408 * |
|
3409 * var keys = [ |
|
3410 * { 'dir': 'left', 'code': 97 }, |
|
3411 * { 'dir': 'right', 'code': 100 } |
|
3412 * ]; |
|
3413 * |
|
3414 * _.indexBy(keys, 'dir'); |
|
3415 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } |
|
3416 * |
|
3417 * _.indexBy(keys, function(key) { return String.fromCharCode(key.code); }); |
|
3418 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
3419 * |
|
3420 * _.indexBy(characters, function(key) { this.fromCharCode(key.code); }, String); |
|
3421 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
3422 */ |
|
3423 var indexBy = createAggregator(function(result, value, key) { |
|
3424 result[key] = value; |
|
3425 }); |
|
3426 |
|
3427 /** |
|
3428 * Invokes the method named by `methodName` on each element in the `collection` |
|
3429 * returning an array of the results of each invoked method. Additional arguments |
|
3430 * will be provided to each invoked method. If `methodName` is a function it |
|
3431 * will be invoked for, and `this` bound to, each element in the `collection`. |
|
3432 * |
|
3433 * @static |
|
3434 * @memberOf _ |
|
3435 * @category Collections |
|
3436 * @param {Array|Object|string} collection The collection to iterate over. |
|
3437 * @param {Function|string} methodName The name of the method to invoke or |
|
3438 * the function invoked per iteration. |
|
3439 * @param {...*} [arg] Arguments to invoke the method with. |
|
3440 * @returns {Array} Returns a new array of the results of each invoked method. |
|
3441 * @example |
|
3442 * |
|
3443 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); |
|
3444 * // => [[1, 5, 7], [1, 2, 3]] |
|
3445 * |
|
3446 * _.invoke([123, 456], String.prototype.split, ''); |
|
3447 * // => [['1', '2', '3'], ['4', '5', '6']] |
|
3448 */ |
|
3449 function invoke(collection, methodName) { |
|
3450 var args = slice(arguments, 2), |
|
3451 index = -1, |
|
3452 isFunc = typeof methodName == 'function', |
|
3453 length = collection ? collection.length : 0, |
|
3454 result = Array(typeof length == 'number' ? length : 0); |
|
3455 |
|
3456 forEach(collection, function(value) { |
|
3457 result[++index] = (isFunc ? methodName : value[methodName]).apply(value, args); |
|
3458 }); |
|
3459 return result; |
|
3460 } |
|
3461 |
|
3462 /** |
|
3463 * Creates an array of values by running each element in the collection |
|
3464 * through the callback. The callback is bound to `thisArg` and invoked with |
|
3465 * three arguments; (value, index|key, collection). |
|
3466 * |
|
3467 * If a property name is provided for `callback` the created "_.pluck" style |
|
3468 * callback will return the property value of the given element. |
|
3469 * |
|
3470 * If an object is provided for `callback` the created "_.where" style callback |
|
3471 * will return `true` for elements that have the properties of the given object, |
|
3472 * else `false`. |
|
3473 * |
|
3474 * @static |
|
3475 * @memberOf _ |
|
3476 * @alias collect |
|
3477 * @category Collections |
|
3478 * @param {Array|Object|string} collection The collection to iterate over. |
|
3479 * @param {Function|Object|string} [callback=identity] The function called |
|
3480 * per iteration. If a property name or object is provided it will be used |
|
3481 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3482 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3483 * @returns {Array} Returns a new array of the results of each `callback` execution. |
|
3484 * @example |
|
3485 * |
|
3486 * _.map([1, 2, 3], function(num) { return num * 3; }); |
|
3487 * // => [3, 6, 9] |
|
3488 * |
|
3489 * _.map({ 'one': 1, 'two': 2, 'three': 3 }, function(num) { return num * 3; }); |
|
3490 * // => [3, 6, 9] (property order is not guaranteed across environments) |
|
3491 * |
|
3492 * var characters = [ |
|
3493 * { 'name': 'barney', 'age': 36 }, |
|
3494 * { 'name': 'fred', 'age': 40 } |
|
3495 * ]; |
|
3496 * |
|
3497 * // using "_.pluck" callback shorthand |
|
3498 * _.map(characters, 'name'); |
|
3499 * // => ['barney', 'fred'] |
|
3500 */ |
|
3501 function map(collection, callback, thisArg) { |
|
3502 var index = -1, |
|
3503 length = collection ? collection.length : 0; |
|
3504 |
|
3505 callback = lodash.createCallback(callback, thisArg, 3); |
|
3506 if (typeof length == 'number') { |
|
3507 var result = Array(length); |
|
3508 while (++index < length) { |
|
3509 result[index] = callback(collection[index], index, collection); |
|
3510 } |
|
3511 } else { |
|
3512 result = []; |
|
3513 forOwn(collection, function(value, key, collection) { |
|
3514 result[++index] = callback(value, key, collection); |
|
3515 }); |
|
3516 } |
|
3517 return result; |
|
3518 } |
|
3519 |
|
3520 /** |
|
3521 * Retrieves the maximum value of a collection. If the collection is empty or |
|
3522 * falsey `-Infinity` is returned. If a callback is provided it will be executed |
|
3523 * for each value in the collection to generate the criterion by which the value |
|
3524 * is ranked. The callback is bound to `thisArg` and invoked with three |
|
3525 * arguments; (value, index, collection). |
|
3526 * |
|
3527 * If a property name is provided for `callback` the created "_.pluck" style |
|
3528 * callback will return the property value of the given element. |
|
3529 * |
|
3530 * If an object is provided for `callback` the created "_.where" style callback |
|
3531 * will return `true` for elements that have the properties of the given object, |
|
3532 * else `false`. |
|
3533 * |
|
3534 * @static |
|
3535 * @memberOf _ |
|
3536 * @category Collections |
|
3537 * @param {Array|Object|string} collection The collection to iterate over. |
|
3538 * @param {Function|Object|string} [callback=identity] The function called |
|
3539 * per iteration. If a property name or object is provided it will be used |
|
3540 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3541 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3542 * @returns {*} Returns the maximum value. |
|
3543 * @example |
|
3544 * |
|
3545 * _.max([4, 2, 8, 6]); |
|
3546 * // => 8 |
|
3547 * |
|
3548 * var characters = [ |
|
3549 * { 'name': 'barney', 'age': 36 }, |
|
3550 * { 'name': 'fred', 'age': 40 } |
|
3551 * ]; |
|
3552 * |
|
3553 * _.max(characters, function(chr) { return chr.age; }); |
|
3554 * // => { 'name': 'fred', 'age': 40 }; |
|
3555 * |
|
3556 * // using "_.pluck" callback shorthand |
|
3557 * _.max(characters, 'age'); |
|
3558 * // => { 'name': 'fred', 'age': 40 }; |
|
3559 */ |
|
3560 function max(collection, callback, thisArg) { |
|
3561 var computed = -Infinity, |
|
3562 result = computed; |
|
3563 |
|
3564 // allows working with functions like `_.map` without using |
|
3565 // their `index` argument as a callback |
|
3566 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { |
|
3567 callback = null; |
|
3568 } |
|
3569 if (callback == null && isArray(collection)) { |
|
3570 var index = -1, |
|
3571 length = collection.length; |
|
3572 |
|
3573 while (++index < length) { |
|
3574 var value = collection[index]; |
|
3575 if (value > result) { |
|
3576 result = value; |
|
3577 } |
|
3578 } |
|
3579 } else { |
|
3580 callback = (callback == null && isString(collection)) |
|
3581 ? charAtCallback |
|
3582 : lodash.createCallback(callback, thisArg, 3); |
|
3583 |
|
3584 forEach(collection, function(value, index, collection) { |
|
3585 var current = callback(value, index, collection); |
|
3586 if (current > computed) { |
|
3587 computed = current; |
|
3588 result = value; |
|
3589 } |
|
3590 }); |
|
3591 } |
|
3592 return result; |
|
3593 } |
|
3594 |
|
3595 /** |
|
3596 * Retrieves the minimum value of a collection. If the collection is empty or |
|
3597 * falsey `Infinity` is returned. If a callback is provided it will be executed |
|
3598 * for each value in the collection to generate the criterion by which the value |
|
3599 * is ranked. The callback is bound to `thisArg` and invoked with three |
|
3600 * arguments; (value, index, collection). |
|
3601 * |
|
3602 * If a property name is provided for `callback` the created "_.pluck" style |
|
3603 * callback will return the property value of the given element. |
|
3604 * |
|
3605 * If an object is provided for `callback` the created "_.where" style callback |
|
3606 * will return `true` for elements that have the properties of the given object, |
|
3607 * else `false`. |
|
3608 * |
|
3609 * @static |
|
3610 * @memberOf _ |
|
3611 * @category Collections |
|
3612 * @param {Array|Object|string} collection The collection to iterate over. |
|
3613 * @param {Function|Object|string} [callback=identity] The function called |
|
3614 * per iteration. If a property name or object is provided it will be used |
|
3615 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3616 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3617 * @returns {*} Returns the minimum value. |
|
3618 * @example |
|
3619 * |
|
3620 * _.min([4, 2, 8, 6]); |
|
3621 * // => 2 |
|
3622 * |
|
3623 * var characters = [ |
|
3624 * { 'name': 'barney', 'age': 36 }, |
|
3625 * { 'name': 'fred', 'age': 40 } |
|
3626 * ]; |
|
3627 * |
|
3628 * _.min(characters, function(chr) { return chr.age; }); |
|
3629 * // => { 'name': 'barney', 'age': 36 }; |
|
3630 * |
|
3631 * // using "_.pluck" callback shorthand |
|
3632 * _.min(characters, 'age'); |
|
3633 * // => { 'name': 'barney', 'age': 36 }; |
|
3634 */ |
|
3635 function min(collection, callback, thisArg) { |
|
3636 var computed = Infinity, |
|
3637 result = computed; |
|
3638 |
|
3639 // allows working with functions like `_.map` without using |
|
3640 // their `index` argument as a callback |
|
3641 if (typeof callback != 'function' && thisArg && thisArg[callback] === collection) { |
|
3642 callback = null; |
|
3643 } |
|
3644 if (callback == null && isArray(collection)) { |
|
3645 var index = -1, |
|
3646 length = collection.length; |
|
3647 |
|
3648 while (++index < length) { |
|
3649 var value = collection[index]; |
|
3650 if (value < result) { |
|
3651 result = value; |
|
3652 } |
|
3653 } |
|
3654 } else { |
|
3655 callback = (callback == null && isString(collection)) |
|
3656 ? charAtCallback |
|
3657 : lodash.createCallback(callback, thisArg, 3); |
|
3658 |
|
3659 forEach(collection, function(value, index, collection) { |
|
3660 var current = callback(value, index, collection); |
|
3661 if (current < computed) { |
|
3662 computed = current; |
|
3663 result = value; |
|
3664 } |
|
3665 }); |
|
3666 } |
|
3667 return result; |
|
3668 } |
|
3669 |
|
3670 /** |
|
3671 * Retrieves the value of a specified property from all elements in the collection. |
|
3672 * |
|
3673 * @static |
|
3674 * @memberOf _ |
|
3675 * @type Function |
|
3676 * @category Collections |
|
3677 * @param {Array|Object|string} collection The collection to iterate over. |
|
3678 * @param {string} property The name of the property to pluck. |
|
3679 * @returns {Array} Returns a new array of property values. |
|
3680 * @example |
|
3681 * |
|
3682 * var characters = [ |
|
3683 * { 'name': 'barney', 'age': 36 }, |
|
3684 * { 'name': 'fred', 'age': 40 } |
|
3685 * ]; |
|
3686 * |
|
3687 * _.pluck(characters, 'name'); |
|
3688 * // => ['barney', 'fred'] |
|
3689 */ |
|
3690 var pluck = map; |
|
3691 |
|
3692 /** |
|
3693 * Reduces a collection to a value which is the accumulated result of running |
|
3694 * each element in the collection through the callback, where each successive |
|
3695 * callback execution consumes the return value of the previous execution. If |
|
3696 * `accumulator` is not provided the first element of the collection will be |
|
3697 * used as the initial `accumulator` value. The callback is bound to `thisArg` |
|
3698 * and invoked with four arguments; (accumulator, value, index|key, collection). |
|
3699 * |
|
3700 * @static |
|
3701 * @memberOf _ |
|
3702 * @alias foldl, inject |
|
3703 * @category Collections |
|
3704 * @param {Array|Object|string} collection The collection to iterate over. |
|
3705 * @param {Function} [callback=identity] The function called per iteration. |
|
3706 * @param {*} [accumulator] Initial value of the accumulator. |
|
3707 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3708 * @returns {*} Returns the accumulated value. |
|
3709 * @example |
|
3710 * |
|
3711 * var sum = _.reduce([1, 2, 3], function(sum, num) { |
|
3712 * return sum + num; |
|
3713 * }); |
|
3714 * // => 6 |
|
3715 * |
|
3716 * var mapped = _.reduce({ 'a': 1, 'b': 2, 'c': 3 }, function(result, num, key) { |
|
3717 * result[key] = num * 3; |
|
3718 * return result; |
|
3719 * }, {}); |
|
3720 * // => { 'a': 3, 'b': 6, 'c': 9 } |
|
3721 */ |
|
3722 function reduce(collection, callback, accumulator, thisArg) { |
|
3723 if (!collection) return accumulator; |
|
3724 var noaccum = arguments.length < 3; |
|
3725 callback = lodash.createCallback(callback, thisArg, 4); |
|
3726 |
|
3727 var index = -1, |
|
3728 length = collection.length; |
|
3729 |
|
3730 if (typeof length == 'number') { |
|
3731 if (noaccum) { |
|
3732 accumulator = collection[++index]; |
|
3733 } |
|
3734 while (++index < length) { |
|
3735 accumulator = callback(accumulator, collection[index], index, collection); |
|
3736 } |
|
3737 } else { |
|
3738 forOwn(collection, function(value, index, collection) { |
|
3739 accumulator = noaccum |
|
3740 ? (noaccum = false, value) |
|
3741 : callback(accumulator, value, index, collection) |
|
3742 }); |
|
3743 } |
|
3744 return accumulator; |
|
3745 } |
|
3746 |
|
3747 /** |
|
3748 * This method is like `_.reduce` except that it iterates over elements |
|
3749 * of a `collection` from right to left. |
|
3750 * |
|
3751 * @static |
|
3752 * @memberOf _ |
|
3753 * @alias foldr |
|
3754 * @category Collections |
|
3755 * @param {Array|Object|string} collection The collection to iterate over. |
|
3756 * @param {Function} [callback=identity] The function called per iteration. |
|
3757 * @param {*} [accumulator] Initial value of the accumulator. |
|
3758 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3759 * @returns {*} Returns the accumulated value. |
|
3760 * @example |
|
3761 * |
|
3762 * var list = [[0, 1], [2, 3], [4, 5]]; |
|
3763 * var flat = _.reduceRight(list, function(a, b) { return a.concat(b); }, []); |
|
3764 * // => [4, 5, 2, 3, 0, 1] |
|
3765 */ |
|
3766 function reduceRight(collection, callback, accumulator, thisArg) { |
|
3767 var noaccum = arguments.length < 3; |
|
3768 callback = lodash.createCallback(callback, thisArg, 4); |
|
3769 forEachRight(collection, function(value, index, collection) { |
|
3770 accumulator = noaccum |
|
3771 ? (noaccum = false, value) |
|
3772 : callback(accumulator, value, index, collection); |
|
3773 }); |
|
3774 return accumulator; |
|
3775 } |
|
3776 |
|
3777 /** |
|
3778 * The opposite of `_.filter` this method returns the elements of a |
|
3779 * collection that the callback does **not** return truey for. |
|
3780 * |
|
3781 * If a property name is provided for `callback` the created "_.pluck" style |
|
3782 * callback will return the property value of the given element. |
|
3783 * |
|
3784 * If an object is provided for `callback` the created "_.where" style callback |
|
3785 * will return `true` for elements that have the properties of the given object, |
|
3786 * else `false`. |
|
3787 * |
|
3788 * @static |
|
3789 * @memberOf _ |
|
3790 * @category Collections |
|
3791 * @param {Array|Object|string} collection The collection to iterate over. |
|
3792 * @param {Function|Object|string} [callback=identity] The function called |
|
3793 * per iteration. If a property name or object is provided it will be used |
|
3794 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3795 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3796 * @returns {Array} Returns a new array of elements that failed the callback check. |
|
3797 * @example |
|
3798 * |
|
3799 * var odds = _.reject([1, 2, 3, 4, 5, 6], function(num) { return num % 2 == 0; }); |
|
3800 * // => [1, 3, 5] |
|
3801 * |
|
3802 * var characters = [ |
|
3803 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3804 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3805 * ]; |
|
3806 * |
|
3807 * // using "_.pluck" callback shorthand |
|
3808 * _.reject(characters, 'blocked'); |
|
3809 * // => [{ 'name': 'barney', 'age': 36, 'blocked': false }] |
|
3810 * |
|
3811 * // using "_.where" callback shorthand |
|
3812 * _.reject(characters, { 'age': 36 }); |
|
3813 * // => [{ 'name': 'fred', 'age': 40, 'blocked': true }] |
|
3814 */ |
|
3815 function reject(collection, callback, thisArg) { |
|
3816 callback = lodash.createCallback(callback, thisArg, 3); |
|
3817 return filter(collection, function(value, index, collection) { |
|
3818 return !callback(value, index, collection); |
|
3819 }); |
|
3820 } |
|
3821 |
|
3822 /** |
|
3823 * Retrieves a random element or `n` random elements from a collection. |
|
3824 * |
|
3825 * @static |
|
3826 * @memberOf _ |
|
3827 * @category Collections |
|
3828 * @param {Array|Object|string} collection The collection to sample. |
|
3829 * @param {number} [n] The number of elements to sample. |
|
3830 * @param- {Object} [guard] Allows working with functions like `_.map` |
|
3831 * without using their `index` arguments as `n`. |
|
3832 * @returns {Array} Returns the random sample(s) of `collection`. |
|
3833 * @example |
|
3834 * |
|
3835 * _.sample([1, 2, 3, 4]); |
|
3836 * // => 2 |
|
3837 * |
|
3838 * _.sample([1, 2, 3, 4], 2); |
|
3839 * // => [3, 1] |
|
3840 */ |
|
3841 function sample(collection, n, guard) { |
|
3842 if (collection && typeof collection.length != 'number') { |
|
3843 collection = values(collection); |
|
3844 } |
|
3845 if (n == null || guard) { |
|
3846 return collection ? collection[baseRandom(0, collection.length - 1)] : undefined; |
|
3847 } |
|
3848 var result = shuffle(collection); |
|
3849 result.length = nativeMin(nativeMax(0, n), result.length); |
|
3850 return result; |
|
3851 } |
|
3852 |
|
3853 /** |
|
3854 * Creates an array of shuffled values, using a version of the Fisher-Yates |
|
3855 * shuffle. See http://en.wikipedia.org/wiki/Fisher-Yates_shuffle. |
|
3856 * |
|
3857 * @static |
|
3858 * @memberOf _ |
|
3859 * @category Collections |
|
3860 * @param {Array|Object|string} collection The collection to shuffle. |
|
3861 * @returns {Array} Returns a new shuffled collection. |
|
3862 * @example |
|
3863 * |
|
3864 * _.shuffle([1, 2, 3, 4, 5, 6]); |
|
3865 * // => [4, 1, 6, 3, 5, 2] |
|
3866 */ |
|
3867 function shuffle(collection) { |
|
3868 var index = -1, |
|
3869 length = collection ? collection.length : 0, |
|
3870 result = Array(typeof length == 'number' ? length : 0); |
|
3871 |
|
3872 forEach(collection, function(value) { |
|
3873 var rand = baseRandom(0, ++index); |
|
3874 result[index] = result[rand]; |
|
3875 result[rand] = value; |
|
3876 }); |
|
3877 return result; |
|
3878 } |
|
3879 |
|
3880 /** |
|
3881 * Gets the size of the `collection` by returning `collection.length` for arrays |
|
3882 * and array-like objects or the number of own enumerable properties for objects. |
|
3883 * |
|
3884 * @static |
|
3885 * @memberOf _ |
|
3886 * @category Collections |
|
3887 * @param {Array|Object|string} collection The collection to inspect. |
|
3888 * @returns {number} Returns `collection.length` or number of own enumerable properties. |
|
3889 * @example |
|
3890 * |
|
3891 * _.size([1, 2]); |
|
3892 * // => 2 |
|
3893 * |
|
3894 * _.size({ 'one': 1, 'two': 2, 'three': 3 }); |
|
3895 * // => 3 |
|
3896 * |
|
3897 * _.size('pebbles'); |
|
3898 * // => 7 |
|
3899 */ |
|
3900 function size(collection) { |
|
3901 var length = collection ? collection.length : 0; |
|
3902 return typeof length == 'number' ? length : keys(collection).length; |
|
3903 } |
|
3904 |
|
3905 /** |
|
3906 * Checks if the callback returns a truey value for **any** element of a |
|
3907 * collection. The function returns as soon as it finds a passing value and |
|
3908 * does not iterate over the entire collection. The callback is bound to |
|
3909 * `thisArg` and invoked with three arguments; (value, index|key, collection). |
|
3910 * |
|
3911 * If a property name is provided for `callback` the created "_.pluck" style |
|
3912 * callback will return the property value of the given element. |
|
3913 * |
|
3914 * If an object is provided for `callback` the created "_.where" style callback |
|
3915 * will return `true` for elements that have the properties of the given object, |
|
3916 * else `false`. |
|
3917 * |
|
3918 * @static |
|
3919 * @memberOf _ |
|
3920 * @alias any |
|
3921 * @category Collections |
|
3922 * @param {Array|Object|string} collection The collection to iterate over. |
|
3923 * @param {Function|Object|string} [callback=identity] The function called |
|
3924 * per iteration. If a property name or object is provided it will be used |
|
3925 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3926 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3927 * @returns {boolean} Returns `true` if any element passed the callback check, |
|
3928 * else `false`. |
|
3929 * @example |
|
3930 * |
|
3931 * _.some([null, 0, 'yes', false], Boolean); |
|
3932 * // => true |
|
3933 * |
|
3934 * var characters = [ |
|
3935 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
|
3936 * { 'name': 'fred', 'age': 40, 'blocked': true } |
|
3937 * ]; |
|
3938 * |
|
3939 * // using "_.pluck" callback shorthand |
|
3940 * _.some(characters, 'blocked'); |
|
3941 * // => true |
|
3942 * |
|
3943 * // using "_.where" callback shorthand |
|
3944 * _.some(characters, { 'age': 1 }); |
|
3945 * // => false |
|
3946 */ |
|
3947 function some(collection, callback, thisArg) { |
|
3948 var result; |
|
3949 callback = lodash.createCallback(callback, thisArg, 3); |
|
3950 |
|
3951 var index = -1, |
|
3952 length = collection ? collection.length : 0; |
|
3953 |
|
3954 if (typeof length == 'number') { |
|
3955 while (++index < length) { |
|
3956 if ((result = callback(collection[index], index, collection))) { |
|
3957 break; |
|
3958 } |
|
3959 } |
|
3960 } else { |
|
3961 forOwn(collection, function(value, index, collection) { |
|
3962 return !(result = callback(value, index, collection)); |
|
3963 }); |
|
3964 } |
|
3965 return !!result; |
|
3966 } |
|
3967 |
|
3968 /** |
|
3969 * Creates an array of elements, sorted in ascending order by the results of |
|
3970 * running each element in a collection through the callback. This method |
|
3971 * performs a stable sort, that is, it will preserve the original sort order |
|
3972 * of equal elements. The callback is bound to `thisArg` and invoked with |
|
3973 * three arguments; (value, index|key, collection). |
|
3974 * |
|
3975 * If a property name is provided for `callback` the created "_.pluck" style |
|
3976 * callback will return the property value of the given element. |
|
3977 * |
|
3978 * If an array of property names is provided for `callback` the collection |
|
3979 * will be sorted by each property value. |
|
3980 * |
|
3981 * If an object is provided for `callback` the created "_.where" style callback |
|
3982 * will return `true` for elements that have the properties of the given object, |
|
3983 * else `false`. |
|
3984 * |
|
3985 * @static |
|
3986 * @memberOf _ |
|
3987 * @category Collections |
|
3988 * @param {Array|Object|string} collection The collection to iterate over. |
|
3989 * @param {Array|Function|Object|string} [callback=identity] The function called |
|
3990 * per iteration. If a property name or object is provided it will be used |
|
3991 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
3992 * @param {*} [thisArg] The `this` binding of `callback`. |
|
3993 * @returns {Array} Returns a new array of sorted elements. |
|
3994 * @example |
|
3995 * |
|
3996 * _.sortBy([1, 2, 3], function(num) { return Math.sin(num); }); |
|
3997 * // => [3, 1, 2] |
|
3998 * |
|
3999 * _.sortBy([1, 2, 3], function(num) { return this.sin(num); }, Math); |
|
4000 * // => [3, 1, 2] |
|
4001 * |
|
4002 * var characters = [ |
|
4003 * { 'name': 'barney', 'age': 36 }, |
|
4004 * { 'name': 'fred', 'age': 40 }, |
|
4005 * { 'name': 'barney', 'age': 26 }, |
|
4006 * { 'name': 'fred', 'age': 30 } |
|
4007 * ]; |
|
4008 * |
|
4009 * // using "_.pluck" callback shorthand |
|
4010 * _.map(_.sortBy(characters, 'age'), _.values); |
|
4011 * // => [['barney', 26], ['fred', 30], ['barney', 36], ['fred', 40]] |
|
4012 * |
|
4013 * // sorting by multiple properties |
|
4014 * _.map(_.sortBy(characters, ['name', 'age']), _.values); |
|
4015 * // = > [['barney', 26], ['barney', 36], ['fred', 30], ['fred', 40]] |
|
4016 */ |
|
4017 function sortBy(collection, callback, thisArg) { |
|
4018 var index = -1, |
|
4019 isArr = isArray(callback), |
|
4020 length = collection ? collection.length : 0, |
|
4021 result = Array(typeof length == 'number' ? length : 0); |
|
4022 |
|
4023 if (!isArr) { |
|
4024 callback = lodash.createCallback(callback, thisArg, 3); |
|
4025 } |
|
4026 forEach(collection, function(value, key, collection) { |
|
4027 var object = result[++index] = getObject(); |
|
4028 if (isArr) { |
|
4029 object.criteria = map(callback, function(key) { return value[key]; }); |
|
4030 } else { |
|
4031 (object.criteria = getArray())[0] = callback(value, key, collection); |
|
4032 } |
|
4033 object.index = index; |
|
4034 object.value = value; |
|
4035 }); |
|
4036 |
|
4037 length = result.length; |
|
4038 result.sort(compareAscending); |
|
4039 while (length--) { |
|
4040 var object = result[length]; |
|
4041 result[length] = object.value; |
|
4042 if (!isArr) { |
|
4043 releaseArray(object.criteria); |
|
4044 } |
|
4045 releaseObject(object); |
|
4046 } |
|
4047 return result; |
|
4048 } |
|
4049 |
|
4050 /** |
|
4051 * Converts the `collection` to an array. |
|
4052 * |
|
4053 * @static |
|
4054 * @memberOf _ |
|
4055 * @category Collections |
|
4056 * @param {Array|Object|string} collection The collection to convert. |
|
4057 * @returns {Array} Returns the new converted array. |
|
4058 * @example |
|
4059 * |
|
4060 * (function() { return _.toArray(arguments).slice(1); })(1, 2, 3, 4); |
|
4061 * // => [2, 3, 4] |
|
4062 */ |
|
4063 function toArray(collection) { |
|
4064 if (collection && typeof collection.length == 'number') { |
|
4065 return slice(collection); |
|
4066 } |
|
4067 return values(collection); |
|
4068 } |
|
4069 |
|
4070 /** |
|
4071 * Performs a deep comparison of each element in a `collection` to the given |
|
4072 * `properties` object, returning an array of all elements that have equivalent |
|
4073 * property values. |
|
4074 * |
|
4075 * @static |
|
4076 * @memberOf _ |
|
4077 * @type Function |
|
4078 * @category Collections |
|
4079 * @param {Array|Object|string} collection The collection to iterate over. |
|
4080 * @param {Object} props The object of property values to filter by. |
|
4081 * @returns {Array} Returns a new array of elements that have the given properties. |
|
4082 * @example |
|
4083 * |
|
4084 * var characters = [ |
|
4085 * { 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }, |
|
4086 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } |
|
4087 * ]; |
|
4088 * |
|
4089 * _.where(characters, { 'age': 36 }); |
|
4090 * // => [{ 'name': 'barney', 'age': 36, 'pets': ['hoppy'] }] |
|
4091 * |
|
4092 * _.where(characters, { 'pets': ['dino'] }); |
|
4093 * // => [{ 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] }] |
|
4094 */ |
|
4095 var where = filter; |
|
4096 |
|
4097 /*--------------------------------------------------------------------------*/ |
|
4098 |
|
4099 /** |
|
4100 * Creates an array with all falsey values removed. The values `false`, `null`, |
4489 * Creates an array with all falsey values removed. The values `false`, `null`, |
4101 * `0`, `""`, `undefined`, and `NaN` are all falsey. |
4490 * `0`, `""`, `undefined`, and `NaN` are falsey. |
4102 * |
4491 * |
4103 * @static |
4492 * @static |
4104 * @memberOf _ |
4493 * @memberOf _ |
4105 * @category Arrays |
4494 * @category Array |
4106 * @param {Array} array The array to compact. |
4495 * @param {Array} array The array to compact. |
4107 * @returns {Array} Returns a new array of filtered values. |
4496 * @returns {Array} Returns the new array of filtered values. |
4108 * @example |
4497 * @example |
4109 * |
4498 * |
4110 * _.compact([0, 1, false, 2, '', 3]); |
4499 * _.compact([0, 1, false, 2, '', 3]); |
4111 * // => [1, 2, 3] |
4500 * // => [1, 2, 3] |
4112 */ |
4501 */ |
4113 function compact(array) { |
4502 function compact(array) { |
4114 var index = -1, |
4503 var index = -1, |
4115 length = array ? array.length : 0, |
4504 length = array ? array.length : 0, |
|
4505 resIndex = -1, |
4116 result = []; |
4506 result = []; |
4117 |
4507 |
4118 while (++index < length) { |
4508 while (++index < length) { |
4119 var value = array[index]; |
4509 var value = array[index]; |
4120 if (value) { |
4510 if (value) { |
4121 result.push(value); |
4511 result[++resIndex] = value; |
4122 } |
4512 } |
4123 } |
4513 } |
4124 return result; |
4514 return result; |
4125 } |
4515 } |
4126 |
4516 |
4127 /** |
4517 /** |
4128 * Creates an array excluding all values of the provided arrays using strict |
4518 * Creates an array of unique `array` values not included in the other |
4129 * equality for comparisons, i.e. `===`. |
4519 * provided arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
4130 * |
4520 * for equality comparisons. |
4131 * @static |
4521 * |
4132 * @memberOf _ |
4522 * @static |
4133 * @category Arrays |
4523 * @memberOf _ |
4134 * @param {Array} array The array to process. |
4524 * @category Array |
|
4525 * @param {Array} array The array to inspect. |
4135 * @param {...Array} [values] The arrays of values to exclude. |
4526 * @param {...Array} [values] The arrays of values to exclude. |
4136 * @returns {Array} Returns a new array of filtered values. |
4527 * @returns {Array} Returns the new array of filtered values. |
4137 * @example |
4528 * @example |
4138 * |
4529 * |
4139 * _.difference([1, 2, 3, 4, 5], [5, 2, 10]); |
4530 * _.difference([1, 2, 3], [4, 2]); |
4140 * // => [1, 3, 4] |
4531 * // => [1, 3] |
4141 */ |
4532 */ |
4142 function difference(array) { |
4533 var difference = restParam(function(array, values) { |
4143 return baseDifference(array, baseFlatten(arguments, true, true, 1)); |
4534 return (isObjectLike(array) && isArrayLike(array)) |
|
4535 ? baseDifference(array, baseFlatten(values, false, true)) |
|
4536 : []; |
|
4537 }); |
|
4538 |
|
4539 /** |
|
4540 * Creates a slice of `array` with `n` elements dropped from the beginning. |
|
4541 * |
|
4542 * @static |
|
4543 * @memberOf _ |
|
4544 * @category Array |
|
4545 * @param {Array} array The array to query. |
|
4546 * @param {number} [n=1] The number of elements to drop. |
|
4547 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
4548 * @returns {Array} Returns the slice of `array`. |
|
4549 * @example |
|
4550 * |
|
4551 * _.drop([1, 2, 3]); |
|
4552 * // => [2, 3] |
|
4553 * |
|
4554 * _.drop([1, 2, 3], 2); |
|
4555 * // => [3] |
|
4556 * |
|
4557 * _.drop([1, 2, 3], 5); |
|
4558 * // => [] |
|
4559 * |
|
4560 * _.drop([1, 2, 3], 0); |
|
4561 * // => [1, 2, 3] |
|
4562 */ |
|
4563 function drop(array, n, guard) { |
|
4564 var length = array ? array.length : 0; |
|
4565 if (!length) { |
|
4566 return []; |
|
4567 } |
|
4568 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
|
4569 n = 1; |
|
4570 } |
|
4571 return baseSlice(array, n < 0 ? 0 : n); |
|
4572 } |
|
4573 |
|
4574 /** |
|
4575 * Creates a slice of `array` with `n` elements dropped from the end. |
|
4576 * |
|
4577 * @static |
|
4578 * @memberOf _ |
|
4579 * @category Array |
|
4580 * @param {Array} array The array to query. |
|
4581 * @param {number} [n=1] The number of elements to drop. |
|
4582 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
4583 * @returns {Array} Returns the slice of `array`. |
|
4584 * @example |
|
4585 * |
|
4586 * _.dropRight([1, 2, 3]); |
|
4587 * // => [1, 2] |
|
4588 * |
|
4589 * _.dropRight([1, 2, 3], 2); |
|
4590 * // => [1] |
|
4591 * |
|
4592 * _.dropRight([1, 2, 3], 5); |
|
4593 * // => [] |
|
4594 * |
|
4595 * _.dropRight([1, 2, 3], 0); |
|
4596 * // => [1, 2, 3] |
|
4597 */ |
|
4598 function dropRight(array, n, guard) { |
|
4599 var length = array ? array.length : 0; |
|
4600 if (!length) { |
|
4601 return []; |
|
4602 } |
|
4603 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
|
4604 n = 1; |
|
4605 } |
|
4606 n = length - (+n || 0); |
|
4607 return baseSlice(array, 0, n < 0 ? 0 : n); |
|
4608 } |
|
4609 |
|
4610 /** |
|
4611 * Creates a slice of `array` excluding elements dropped from the end. |
|
4612 * Elements are dropped until `predicate` returns falsey. The predicate is |
|
4613 * bound to `thisArg` and invoked with three arguments: (value, index, array). |
|
4614 * |
|
4615 * If a property name is provided for `predicate` the created `_.property` |
|
4616 * style callback returns the property value of the given element. |
|
4617 * |
|
4618 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
4619 * style callback returns `true` for elements that have a matching property |
|
4620 * value, else `false`. |
|
4621 * |
|
4622 * If an object is provided for `predicate` the created `_.matches` style |
|
4623 * callback returns `true` for elements that match the properties of the given |
|
4624 * object, else `false`. |
|
4625 * |
|
4626 * @static |
|
4627 * @memberOf _ |
|
4628 * @category Array |
|
4629 * @param {Array} array The array to query. |
|
4630 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
4631 * per iteration. |
|
4632 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
4633 * @returns {Array} Returns the slice of `array`. |
|
4634 * @example |
|
4635 * |
|
4636 * _.dropRightWhile([1, 2, 3], function(n) { |
|
4637 * return n > 1; |
|
4638 * }); |
|
4639 * // => [1] |
|
4640 * |
|
4641 * var users = [ |
|
4642 * { 'user': 'barney', 'active': true }, |
|
4643 * { 'user': 'fred', 'active': false }, |
|
4644 * { 'user': 'pebbles', 'active': false } |
|
4645 * ]; |
|
4646 * |
|
4647 * // using the `_.matches` callback shorthand |
|
4648 * _.pluck(_.dropRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); |
|
4649 * // => ['barney', 'fred'] |
|
4650 * |
|
4651 * // using the `_.matchesProperty` callback shorthand |
|
4652 * _.pluck(_.dropRightWhile(users, 'active', false), 'user'); |
|
4653 * // => ['barney'] |
|
4654 * |
|
4655 * // using the `_.property` callback shorthand |
|
4656 * _.pluck(_.dropRightWhile(users, 'active'), 'user'); |
|
4657 * // => ['barney', 'fred', 'pebbles'] |
|
4658 */ |
|
4659 function dropRightWhile(array, predicate, thisArg) { |
|
4660 return (array && array.length) |
|
4661 ? baseWhile(array, getCallback(predicate, thisArg, 3), true, true) |
|
4662 : []; |
|
4663 } |
|
4664 |
|
4665 /** |
|
4666 * Creates a slice of `array` excluding elements dropped from the beginning. |
|
4667 * Elements are dropped until `predicate` returns falsey. The predicate is |
|
4668 * bound to `thisArg` and invoked with three arguments: (value, index, array). |
|
4669 * |
|
4670 * If a property name is provided for `predicate` the created `_.property` |
|
4671 * style callback returns the property value of the given element. |
|
4672 * |
|
4673 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
4674 * style callback returns `true` for elements that have a matching property |
|
4675 * value, else `false`. |
|
4676 * |
|
4677 * If an object is provided for `predicate` the created `_.matches` style |
|
4678 * callback returns `true` for elements that have the properties of the given |
|
4679 * object, else `false`. |
|
4680 * |
|
4681 * @static |
|
4682 * @memberOf _ |
|
4683 * @category Array |
|
4684 * @param {Array} array The array to query. |
|
4685 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
4686 * per iteration. |
|
4687 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
4688 * @returns {Array} Returns the slice of `array`. |
|
4689 * @example |
|
4690 * |
|
4691 * _.dropWhile([1, 2, 3], function(n) { |
|
4692 * return n < 3; |
|
4693 * }); |
|
4694 * // => [3] |
|
4695 * |
|
4696 * var users = [ |
|
4697 * { 'user': 'barney', 'active': false }, |
|
4698 * { 'user': 'fred', 'active': false }, |
|
4699 * { 'user': 'pebbles', 'active': true } |
|
4700 * ]; |
|
4701 * |
|
4702 * // using the `_.matches` callback shorthand |
|
4703 * _.pluck(_.dropWhile(users, { 'user': 'barney', 'active': false }), 'user'); |
|
4704 * // => ['fred', 'pebbles'] |
|
4705 * |
|
4706 * // using the `_.matchesProperty` callback shorthand |
|
4707 * _.pluck(_.dropWhile(users, 'active', false), 'user'); |
|
4708 * // => ['pebbles'] |
|
4709 * |
|
4710 * // using the `_.property` callback shorthand |
|
4711 * _.pluck(_.dropWhile(users, 'active'), 'user'); |
|
4712 * // => ['barney', 'fred', 'pebbles'] |
|
4713 */ |
|
4714 function dropWhile(array, predicate, thisArg) { |
|
4715 return (array && array.length) |
|
4716 ? baseWhile(array, getCallback(predicate, thisArg, 3), true) |
|
4717 : []; |
|
4718 } |
|
4719 |
|
4720 /** |
|
4721 * Fills elements of `array` with `value` from `start` up to, but not |
|
4722 * including, `end`. |
|
4723 * |
|
4724 * **Note:** This method mutates `array`. |
|
4725 * |
|
4726 * @static |
|
4727 * @memberOf _ |
|
4728 * @category Array |
|
4729 * @param {Array} array The array to fill. |
|
4730 * @param {*} value The value to fill `array` with. |
|
4731 * @param {number} [start=0] The start position. |
|
4732 * @param {number} [end=array.length] The end position. |
|
4733 * @returns {Array} Returns `array`. |
|
4734 * @example |
|
4735 * |
|
4736 * var array = [1, 2, 3]; |
|
4737 * |
|
4738 * _.fill(array, 'a'); |
|
4739 * console.log(array); |
|
4740 * // => ['a', 'a', 'a'] |
|
4741 * |
|
4742 * _.fill(Array(3), 2); |
|
4743 * // => [2, 2, 2] |
|
4744 * |
|
4745 * _.fill([4, 6, 8], '*', 1, 2); |
|
4746 * // => [4, '*', 8] |
|
4747 */ |
|
4748 function fill(array, value, start, end) { |
|
4749 var length = array ? array.length : 0; |
|
4750 if (!length) { |
|
4751 return []; |
|
4752 } |
|
4753 if (start && typeof start != 'number' && isIterateeCall(array, value, start)) { |
|
4754 start = 0; |
|
4755 end = length; |
|
4756 } |
|
4757 return baseFill(array, value, start, end); |
4144 } |
4758 } |
4145 |
4759 |
4146 /** |
4760 /** |
4147 * This method is like `_.find` except that it returns the index of the first |
4761 * This method is like `_.find` except that it returns the index of the first |
4148 * element that passes the callback check, instead of the element itself. |
4762 * element `predicate` returns truthy for instead of the element itself. |
4149 * |
4763 * |
4150 * If a property name is provided for `callback` the created "_.pluck" style |
4764 * If a property name is provided for `predicate` the created `_.property` |
4151 * callback will return the property value of the given element. |
4765 * style callback returns the property value of the given element. |
4152 * |
4766 * |
4153 * If an object is provided for `callback` the created "_.where" style callback |
4767 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
4154 * will return `true` for elements that have the properties of the given object, |
4768 * style callback returns `true` for elements that have a matching property |
4155 * else `false`. |
4769 * value, else `false`. |
4156 * |
4770 * |
4157 * @static |
4771 * If an object is provided for `predicate` the created `_.matches` style |
4158 * @memberOf _ |
4772 * callback returns `true` for elements that have the properties of the given |
4159 * @category Arrays |
4773 * object, else `false`. |
|
4774 * |
|
4775 * @static |
|
4776 * @memberOf _ |
|
4777 * @category Array |
4160 * @param {Array} array The array to search. |
4778 * @param {Array} array The array to search. |
4161 * @param {Function|Object|string} [callback=identity] The function called |
4779 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
4162 * per iteration. If a property name or object is provided it will be used |
4780 * per iteration. |
4163 * to create a "_.pluck" or "_.where" style callback, respectively. |
4781 * @param {*} [thisArg] The `this` binding of `predicate`. |
4164 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4165 * @returns {number} Returns the index of the found element, else `-1`. |
4782 * @returns {number} Returns the index of the found element, else `-1`. |
4166 * @example |
4783 * @example |
4167 * |
4784 * |
4168 * var characters = [ |
4785 * var users = [ |
4169 * { 'name': 'barney', 'age': 36, 'blocked': false }, |
4786 * { 'user': 'barney', 'active': false }, |
4170 * { 'name': 'fred', 'age': 40, 'blocked': true }, |
4787 * { 'user': 'fred', 'active': false }, |
4171 * { 'name': 'pebbles', 'age': 1, 'blocked': false } |
4788 * { 'user': 'pebbles', 'active': true } |
4172 * ]; |
4789 * ]; |
4173 * |
4790 * |
4174 * _.findIndex(characters, function(chr) { |
4791 * _.findIndex(users, function(chr) { |
4175 * return chr.age < 20; |
4792 * return chr.user == 'barney'; |
|
4793 * }); |
|
4794 * // => 0 |
|
4795 * |
|
4796 * // using the `_.matches` callback shorthand |
|
4797 * _.findIndex(users, { 'user': 'fred', 'active': false }); |
|
4798 * // => 1 |
|
4799 * |
|
4800 * // using the `_.matchesProperty` callback shorthand |
|
4801 * _.findIndex(users, 'active', false); |
|
4802 * // => 0 |
|
4803 * |
|
4804 * // using the `_.property` callback shorthand |
|
4805 * _.findIndex(users, 'active'); |
|
4806 * // => 2 |
|
4807 */ |
|
4808 var findIndex = createFindIndex(); |
|
4809 |
|
4810 /** |
|
4811 * This method is like `_.findIndex` except that it iterates over elements |
|
4812 * of `collection` from right to left. |
|
4813 * |
|
4814 * If a property name is provided for `predicate` the created `_.property` |
|
4815 * style callback returns the property value of the given element. |
|
4816 * |
|
4817 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
4818 * style callback returns `true` for elements that have a matching property |
|
4819 * value, else `false`. |
|
4820 * |
|
4821 * If an object is provided for `predicate` the created `_.matches` style |
|
4822 * callback returns `true` for elements that have the properties of the given |
|
4823 * object, else `false`. |
|
4824 * |
|
4825 * @static |
|
4826 * @memberOf _ |
|
4827 * @category Array |
|
4828 * @param {Array} array The array to search. |
|
4829 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
4830 * per iteration. |
|
4831 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
4832 * @returns {number} Returns the index of the found element, else `-1`. |
|
4833 * @example |
|
4834 * |
|
4835 * var users = [ |
|
4836 * { 'user': 'barney', 'active': true }, |
|
4837 * { 'user': 'fred', 'active': false }, |
|
4838 * { 'user': 'pebbles', 'active': false } |
|
4839 * ]; |
|
4840 * |
|
4841 * _.findLastIndex(users, function(chr) { |
|
4842 * return chr.user == 'pebbles'; |
4176 * }); |
4843 * }); |
4177 * // => 2 |
4844 * // => 2 |
4178 * |
4845 * |
4179 * // using "_.where" callback shorthand |
4846 * // using the `_.matches` callback shorthand |
4180 * _.findIndex(characters, { 'age': 36 }); |
4847 * _.findLastIndex(users, { 'user': 'barney', 'active': true }); |
4181 * // => 0 |
4848 * // => 0 |
4182 * |
4849 * |
4183 * // using "_.pluck" callback shorthand |
4850 * // using the `_.matchesProperty` callback shorthand |
4184 * _.findIndex(characters, 'blocked'); |
4851 * _.findLastIndex(users, 'active', false); |
4185 * // => 1 |
4852 * // => 2 |
4186 */ |
4853 * |
4187 function findIndex(array, callback, thisArg) { |
4854 * // using the `_.property` callback shorthand |
4188 var index = -1, |
4855 * _.findLastIndex(users, 'active'); |
4189 length = array ? array.length : 0; |
|
4190 |
|
4191 callback = lodash.createCallback(callback, thisArg, 3); |
|
4192 while (++index < length) { |
|
4193 if (callback(array[index], index, array)) { |
|
4194 return index; |
|
4195 } |
|
4196 } |
|
4197 return -1; |
|
4198 } |
|
4199 |
|
4200 /** |
|
4201 * This method is like `_.findIndex` except that it iterates over elements |
|
4202 * of a `collection` from right to left. |
|
4203 * |
|
4204 * If a property name is provided for `callback` the created "_.pluck" style |
|
4205 * callback will return the property value of the given element. |
|
4206 * |
|
4207 * If an object is provided for `callback` the created "_.where" style callback |
|
4208 * will return `true` for elements that have the properties of the given object, |
|
4209 * else `false`. |
|
4210 * |
|
4211 * @static |
|
4212 * @memberOf _ |
|
4213 * @category Arrays |
|
4214 * @param {Array} array The array to search. |
|
4215 * @param {Function|Object|string} [callback=identity] The function called |
|
4216 * per iteration. If a property name or object is provided it will be used |
|
4217 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4218 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4219 * @returns {number} Returns the index of the found element, else `-1`. |
|
4220 * @example |
|
4221 * |
|
4222 * var characters = [ |
|
4223 * { 'name': 'barney', 'age': 36, 'blocked': true }, |
|
4224 * { 'name': 'fred', 'age': 40, 'blocked': false }, |
|
4225 * { 'name': 'pebbles', 'age': 1, 'blocked': true } |
|
4226 * ]; |
|
4227 * |
|
4228 * _.findLastIndex(characters, function(chr) { |
|
4229 * return chr.age > 30; |
|
4230 * }); |
|
4231 * // => 1 |
|
4232 * |
|
4233 * // using "_.where" callback shorthand |
|
4234 * _.findLastIndex(characters, { 'age': 36 }); |
|
4235 * // => 0 |
4856 * // => 0 |
4236 * |
4857 */ |
4237 * // using "_.pluck" callback shorthand |
4858 var findLastIndex = createFindIndex(true); |
4238 * _.findLastIndex(characters, 'blocked'); |
4859 |
4239 * // => 2 |
4860 /** |
4240 */ |
4861 * Gets the first element of `array`. |
4241 function findLastIndex(array, callback, thisArg) { |
4862 * |
4242 var length = array ? array.length : 0; |
4863 * @static |
4243 callback = lodash.createCallback(callback, thisArg, 3); |
4864 * @memberOf _ |
4244 while (length--) { |
4865 * @alias head |
4245 if (callback(array[length], length, array)) { |
4866 * @category Array |
4246 return length; |
|
4247 } |
|
4248 } |
|
4249 return -1; |
|
4250 } |
|
4251 |
|
4252 /** |
|
4253 * Gets the first element or first `n` elements of an array. If a callback |
|
4254 * is provided elements at the beginning of the array are returned as long |
|
4255 * as the callback returns truey. The callback is bound to `thisArg` and |
|
4256 * invoked with three arguments; (value, index, array). |
|
4257 * |
|
4258 * If a property name is provided for `callback` the created "_.pluck" style |
|
4259 * callback will return the property value of the given element. |
|
4260 * |
|
4261 * If an object is provided for `callback` the created "_.where" style callback |
|
4262 * will return `true` for elements that have the properties of the given object, |
|
4263 * else `false`. |
|
4264 * |
|
4265 * @static |
|
4266 * @memberOf _ |
|
4267 * @alias head, take |
|
4268 * @category Arrays |
|
4269 * @param {Array} array The array to query. |
4867 * @param {Array} array The array to query. |
4270 * @param {Function|Object|number|string} [callback] The function called |
4868 * @returns {*} Returns the first element of `array`. |
4271 * per element or the number of elements to return. If a property name or |
|
4272 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4273 * style callback, respectively. |
|
4274 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4275 * @returns {*} Returns the first element(s) of `array`. |
|
4276 * @example |
4869 * @example |
4277 * |
4870 * |
4278 * _.first([1, 2, 3]); |
4871 * _.first([1, 2, 3]); |
4279 * // => 1 |
4872 * // => 1 |
4280 * |
4873 * |
4281 * _.first([1, 2, 3], 2); |
4874 * _.first([]); |
4282 * // => [1, 2] |
4875 * // => undefined |
4283 * |
4876 */ |
4284 * _.first([1, 2, 3], function(num) { |
4877 function first(array) { |
4285 * return num < 3; |
4878 return array ? array[0] : undefined; |
4286 * }); |
4879 } |
4287 * // => [1, 2] |
4880 |
4288 * |
4881 /** |
4289 * var characters = [ |
4882 * Flattens a nested array. If `isDeep` is `true` the array is recursively |
4290 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, |
4883 * flattened, otherwise it's only flattened a single level. |
4291 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, |
4884 * |
4292 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
4885 * @static |
4293 * ]; |
4886 * @memberOf _ |
4294 * |
4887 * @category Array |
4295 * // using "_.pluck" callback shorthand |
|
4296 * _.first(characters, 'blocked'); |
|
4297 * // => [{ 'name': 'barney', 'blocked': true, 'employer': 'slate' }] |
|
4298 * |
|
4299 * // using "_.where" callback shorthand |
|
4300 * _.pluck(_.first(characters, { 'employer': 'slate' }), 'name'); |
|
4301 * // => ['barney', 'fred'] |
|
4302 */ |
|
4303 function first(array, callback, thisArg) { |
|
4304 var n = 0, |
|
4305 length = array ? array.length : 0; |
|
4306 |
|
4307 if (typeof callback != 'number' && callback != null) { |
|
4308 var index = -1; |
|
4309 callback = lodash.createCallback(callback, thisArg, 3); |
|
4310 while (++index < length && callback(array[index], index, array)) { |
|
4311 n++; |
|
4312 } |
|
4313 } else { |
|
4314 n = callback; |
|
4315 if (n == null || thisArg) { |
|
4316 return array ? array[0] : undefined; |
|
4317 } |
|
4318 } |
|
4319 return slice(array, 0, nativeMin(nativeMax(0, n), length)); |
|
4320 } |
|
4321 |
|
4322 /** |
|
4323 * Flattens a nested array (the nesting can be to any depth). If `isShallow` |
|
4324 * is truey, the array will only be flattened a single level. If a callback |
|
4325 * is provided each element of the array is passed through the callback before |
|
4326 * flattening. The callback is bound to `thisArg` and invoked with three |
|
4327 * arguments; (value, index, array). |
|
4328 * |
|
4329 * If a property name is provided for `callback` the created "_.pluck" style |
|
4330 * callback will return the property value of the given element. |
|
4331 * |
|
4332 * If an object is provided for `callback` the created "_.where" style callback |
|
4333 * will return `true` for elements that have the properties of the given object, |
|
4334 * else `false`. |
|
4335 * |
|
4336 * @static |
|
4337 * @memberOf _ |
|
4338 * @category Arrays |
|
4339 * @param {Array} array The array to flatten. |
4888 * @param {Array} array The array to flatten. |
4340 * @param {boolean} [isShallow=false] A flag to restrict flattening to a single level. |
4889 * @param {boolean} [isDeep] Specify a deep flatten. |
4341 * @param {Function|Object|string} [callback=identity] The function called |
4890 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
4342 * per iteration. If a property name or object is provided it will be used |
4891 * @returns {Array} Returns the new flattened array. |
4343 * to create a "_.pluck" or "_.where" style callback, respectively. |
4892 * @example |
4344 * @param {*} [thisArg] The `this` binding of `callback`. |
4893 * |
4345 * @returns {Array} Returns a new flattened array. |
4894 * _.flatten([1, [2, 3, [4]]]); |
4346 * @example |
4895 * // => [1, 2, 3, [4]] |
4347 * |
4896 * |
4348 * _.flatten([1, [2], [3, [[4]]]]); |
4897 * // using `isDeep` |
4349 * // => [1, 2, 3, 4]; |
4898 * _.flatten([1, [2, 3, [4]]], true); |
4350 * |
4899 * // => [1, 2, 3, 4] |
4351 * _.flatten([1, [2], [3, [[4]]]], true); |
4900 */ |
4352 * // => [1, 2, 3, [[4]]]; |
4901 function flatten(array, isDeep, guard) { |
4353 * |
4902 var length = array ? array.length : 0; |
4354 * var characters = [ |
4903 if (guard && isIterateeCall(array, isDeep, guard)) { |
4355 * { 'name': 'barney', 'age': 30, 'pets': ['hoppy'] }, |
4904 isDeep = false; |
4356 * { 'name': 'fred', 'age': 40, 'pets': ['baby puss', 'dino'] } |
4905 } |
4357 * ]; |
4906 return length ? baseFlatten(array, isDeep) : []; |
4358 * |
4907 } |
4359 * // using "_.pluck" callback shorthand |
4908 |
4360 * _.flatten(characters, 'pets'); |
4909 /** |
4361 * // => ['hoppy', 'baby puss', 'dino'] |
4910 * Recursively flattens a nested array. |
4362 */ |
4911 * |
4363 function flatten(array, isShallow, callback, thisArg) { |
4912 * @static |
4364 // juggle arguments |
4913 * @memberOf _ |
4365 if (typeof isShallow != 'boolean' && isShallow != null) { |
4914 * @category Array |
4366 thisArg = callback; |
4915 * @param {Array} array The array to recursively flatten. |
4367 callback = (typeof isShallow != 'function' && thisArg && thisArg[isShallow] === array) ? null : isShallow; |
4916 * @returns {Array} Returns the new flattened array. |
4368 isShallow = false; |
4917 * @example |
4369 } |
4918 * |
4370 if (callback != null) { |
4919 * _.flattenDeep([1, [2, 3, [4]]]); |
4371 array = map(array, callback, thisArg); |
4920 * // => [1, 2, 3, 4] |
4372 } |
4921 */ |
4373 return baseFlatten(array, isShallow); |
4922 function flattenDeep(array) { |
4374 } |
4923 var length = array ? array.length : 0; |
4375 |
4924 return length ? baseFlatten(array, true) : []; |
4376 /** |
4925 } |
4377 * Gets the index at which the first occurrence of `value` is found using |
4926 |
4378 * strict equality for comparisons, i.e. `===`. If the array is already sorted |
4927 /** |
4379 * providing `true` for `fromIndex` will run a faster binary search. |
4928 * Gets the index at which the first occurrence of `value` is found in `array` |
4380 * |
4929 * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
4381 * @static |
4930 * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
4382 * @memberOf _ |
4931 * from the end of `array`. If `array` is sorted providing `true` for `fromIndex` |
4383 * @category Arrays |
4932 * performs a faster binary search. |
|
4933 * |
|
4934 * @static |
|
4935 * @memberOf _ |
|
4936 * @category Array |
4384 * @param {Array} array The array to search. |
4937 * @param {Array} array The array to search. |
4385 * @param {*} value The value to search for. |
4938 * @param {*} value The value to search for. |
4386 * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
4939 * @param {boolean|number} [fromIndex=0] The index to search from or `true` |
4387 * to perform a binary search on a sorted array. |
4940 * to perform a binary search on a sorted array. |
4388 * @returns {number} Returns the index of the matched value or `-1`. |
4941 * @returns {number} Returns the index of the matched value, else `-1`. |
4389 * @example |
4942 * @example |
4390 * |
4943 * |
4391 * _.indexOf([1, 2, 3, 1, 2, 3], 2); |
4944 * _.indexOf([1, 2, 1, 2], 2); |
4392 * // => 1 |
4945 * // => 1 |
4393 * |
4946 * |
4394 * _.indexOf([1, 2, 3, 1, 2, 3], 2, 3); |
4947 * // using `fromIndex` |
4395 * // => 4 |
4948 * _.indexOf([1, 2, 1, 2], 2, 2); |
4396 * |
4949 * // => 3 |
4397 * _.indexOf([1, 1, 2, 2, 3, 3], 2, true); |
4950 * |
|
4951 * // performing a binary search |
|
4952 * _.indexOf([1, 1, 2, 2], 2, true); |
4398 * // => 2 |
4953 * // => 2 |
4399 */ |
4954 */ |
4400 function indexOf(array, value, fromIndex) { |
4955 function indexOf(array, value, fromIndex) { |
|
4956 var length = array ? array.length : 0; |
|
4957 if (!length) { |
|
4958 return -1; |
|
4959 } |
4401 if (typeof fromIndex == 'number') { |
4960 if (typeof fromIndex == 'number') { |
4402 var length = array ? array.length : 0; |
4961 fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : fromIndex; |
4403 fromIndex = (fromIndex < 0 ? nativeMax(0, length + fromIndex) : fromIndex || 0); |
|
4404 } else if (fromIndex) { |
4962 } else if (fromIndex) { |
4405 var index = sortedIndex(array, value); |
4963 var index = binaryIndex(array, value); |
4406 return array[index] === value ? index : -1; |
4964 if (index < length && |
4407 } |
4965 (value === value ? (value === array[index]) : (array[index] !== array[index]))) { |
4408 return baseIndexOf(array, value, fromIndex); |
4966 return index; |
4409 } |
4967 } |
4410 |
4968 return -1; |
4411 /** |
4969 } |
4412 * Gets all but the last element or last `n` elements of an array. If a |
4970 return baseIndexOf(array, value, fromIndex || 0); |
4413 * callback is provided elements at the end of the array are excluded from |
4971 } |
4414 * the result as long as the callback returns truey. The callback is bound |
4972 |
4415 * to `thisArg` and invoked with three arguments; (value, index, array). |
4973 /** |
4416 * |
4974 * Gets all but the last element of `array`. |
4417 * If a property name is provided for `callback` the created "_.pluck" style |
4975 * |
4418 * callback will return the property value of the given element. |
4976 * @static |
4419 * |
4977 * @memberOf _ |
4420 * If an object is provided for `callback` the created "_.where" style callback |
4978 * @category Array |
4421 * will return `true` for elements that have the properties of the given object, |
|
4422 * else `false`. |
|
4423 * |
|
4424 * @static |
|
4425 * @memberOf _ |
|
4426 * @category Arrays |
|
4427 * @param {Array} array The array to query. |
4979 * @param {Array} array The array to query. |
4428 * @param {Function|Object|number|string} [callback=1] The function called |
4980 * @returns {Array} Returns the slice of `array`. |
4429 * per element or the number of elements to exclude. If a property name or |
|
4430 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4431 * style callback, respectively. |
|
4432 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4433 * @returns {Array} Returns a slice of `array`. |
|
4434 * @example |
4981 * @example |
4435 * |
4982 * |
4436 * _.initial([1, 2, 3]); |
4983 * _.initial([1, 2, 3]); |
4437 * // => [1, 2] |
4984 * // => [1, 2] |
4438 * |
4985 */ |
4439 * _.initial([1, 2, 3], 2); |
4986 function initial(array) { |
4440 * // => [1] |
4987 return dropRight(array, 1); |
4441 * |
4988 } |
4442 * _.initial([1, 2, 3], function(num) { |
4989 |
4443 * return num > 1; |
4990 /** |
4444 * }); |
4991 * Creates an array of unique values that are included in all of the provided |
4445 * // => [1] |
4992 * arrays using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
4446 * |
4993 * for equality comparisons. |
4447 * var characters = [ |
4994 * |
4448 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, |
4995 * @static |
4449 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, |
4996 * @memberOf _ |
4450 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
4997 * @category Array |
4451 * ]; |
4998 * @param {...Array} [arrays] The arrays to inspect. |
4452 * |
4999 * @returns {Array} Returns the new array of shared values. |
4453 * // using "_.pluck" callback shorthand |
5000 * @example |
4454 * _.initial(characters, 'blocked'); |
5001 * _.intersection([1, 2], [4, 2], [2, 1]); |
4455 * // => [{ 'name': 'barney', 'blocked': false, 'employer': 'slate' }] |
5002 * // => [2] |
4456 * |
5003 */ |
4457 * // using "_.where" callback shorthand |
5004 var intersection = restParam(function(arrays) { |
4458 * _.pluck(_.initial(characters, { 'employer': 'na' }), 'name'); |
5005 var othLength = arrays.length, |
4459 * // => ['barney', 'fred'] |
5006 othIndex = othLength, |
4460 */ |
5007 caches = Array(length), |
4461 function initial(array, callback, thisArg) { |
|
4462 var n = 0, |
|
4463 length = array ? array.length : 0; |
|
4464 |
|
4465 if (typeof callback != 'number' && callback != null) { |
|
4466 var index = length; |
|
4467 callback = lodash.createCallback(callback, thisArg, 3); |
|
4468 while (index-- && callback(array[index], index, array)) { |
|
4469 n++; |
|
4470 } |
|
4471 } else { |
|
4472 n = (callback == null || thisArg) ? 1 : callback || n; |
|
4473 } |
|
4474 return slice(array, 0, nativeMin(nativeMax(0, length - n), length)); |
|
4475 } |
|
4476 |
|
4477 /** |
|
4478 * Creates an array of unique values present in all provided arrays using |
|
4479 * strict equality for comparisons, i.e. `===`. |
|
4480 * |
|
4481 * @static |
|
4482 * @memberOf _ |
|
4483 * @category Arrays |
|
4484 * @param {...Array} [array] The arrays to inspect. |
|
4485 * @returns {Array} Returns an array of shared values. |
|
4486 * @example |
|
4487 * |
|
4488 * _.intersection([1, 2, 3], [5, 2, 1, 4], [2, 1]); |
|
4489 * // => [1, 2] |
|
4490 */ |
|
4491 function intersection() { |
|
4492 var args = [], |
|
4493 argsIndex = -1, |
|
4494 argsLength = arguments.length, |
|
4495 caches = getArray(), |
|
4496 indexOf = getIndexOf(), |
5008 indexOf = getIndexOf(), |
4497 trustIndexOf = indexOf === baseIndexOf, |
5009 isCommon = indexOf === baseIndexOf, |
4498 seen = getArray(); |
5010 result = []; |
4499 |
5011 |
4500 while (++argsIndex < argsLength) { |
5012 while (othIndex--) { |
4501 var value = arguments[argsIndex]; |
5013 var value = arrays[othIndex] = isArrayLike(value = arrays[othIndex]) ? value : []; |
4502 if (isArray(value) || isArguments(value)) { |
5014 caches[othIndex] = (isCommon && value.length >= 120) ? createCache(othIndex && value) : null; |
4503 args.push(value); |
5015 } |
4504 caches.push(trustIndexOf && value.length >= largeArraySize && |
5016 var array = arrays[0], |
4505 createCache(argsIndex ? args[argsIndex] : seen)); |
|
4506 } |
|
4507 } |
|
4508 var array = args[0], |
|
4509 index = -1, |
5017 index = -1, |
4510 length = array ? array.length : 0, |
5018 length = array ? array.length : 0, |
4511 result = []; |
5019 seen = caches[0]; |
4512 |
5020 |
4513 outer: |
5021 outer: |
4514 while (++index < length) { |
5022 while (++index < length) { |
4515 var cache = caches[0]; |
|
4516 value = array[index]; |
5023 value = array[index]; |
4517 |
5024 if ((seen ? cacheIndexOf(seen, value) : indexOf(result, value, 0)) < 0) { |
4518 if ((cache ? cacheIndexOf(cache, value) : indexOf(seen, value)) < 0) { |
5025 var othIndex = othLength; |
4519 argsIndex = argsLength; |
5026 while (--othIndex) { |
4520 (cache || seen).push(value); |
5027 var cache = caches[othIndex]; |
4521 while (--argsIndex) { |
5028 if ((cache ? cacheIndexOf(cache, value) : indexOf(arrays[othIndex], value, 0)) < 0) { |
4522 cache = caches[argsIndex]; |
|
4523 if ((cache ? cacheIndexOf(cache, value) : indexOf(args[argsIndex], value)) < 0) { |
|
4524 continue outer; |
5029 continue outer; |
4525 } |
5030 } |
4526 } |
5031 } |
|
5032 if (seen) { |
|
5033 seen.push(value); |
|
5034 } |
4527 result.push(value); |
5035 result.push(value); |
4528 } |
5036 } |
4529 } |
5037 } |
4530 while (argsLength--) { |
|
4531 cache = caches[argsLength]; |
|
4532 if (cache) { |
|
4533 releaseObject(cache); |
|
4534 } |
|
4535 } |
|
4536 releaseArray(caches); |
|
4537 releaseArray(seen); |
|
4538 return result; |
5038 return result; |
4539 } |
5039 }); |
4540 |
5040 |
4541 /** |
5041 /** |
4542 * Gets the last element or last `n` elements of an array. If a callback is |
5042 * Gets the last element of `array`. |
4543 * provided elements at the end of the array are returned as long as the |
5043 * |
4544 * callback returns truey. The callback is bound to `thisArg` and invoked |
5044 * @static |
4545 * with three arguments; (value, index, array). |
5045 * @memberOf _ |
4546 * |
5046 * @category Array |
4547 * If a property name is provided for `callback` the created "_.pluck" style |
|
4548 * callback will return the property value of the given element. |
|
4549 * |
|
4550 * If an object is provided for `callback` the created "_.where" style callback |
|
4551 * will return `true` for elements that have the properties of the given object, |
|
4552 * else `false`. |
|
4553 * |
|
4554 * @static |
|
4555 * @memberOf _ |
|
4556 * @category Arrays |
|
4557 * @param {Array} array The array to query. |
5047 * @param {Array} array The array to query. |
4558 * @param {Function|Object|number|string} [callback] The function called |
5048 * @returns {*} Returns the last element of `array`. |
4559 * per element or the number of elements to return. If a property name or |
|
4560 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4561 * style callback, respectively. |
|
4562 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4563 * @returns {*} Returns the last element(s) of `array`. |
|
4564 * @example |
5049 * @example |
4565 * |
5050 * |
4566 * _.last([1, 2, 3]); |
5051 * _.last([1, 2, 3]); |
4567 * // => 3 |
5052 * // => 3 |
4568 * |
5053 */ |
4569 * _.last([1, 2, 3], 2); |
5054 function last(array) { |
4570 * // => [2, 3] |
5055 var length = array ? array.length : 0; |
4571 * |
5056 return length ? array[length - 1] : undefined; |
4572 * _.last([1, 2, 3], function(num) { |
5057 } |
4573 * return num > 1; |
5058 |
4574 * }); |
5059 /** |
4575 * // => [2, 3] |
5060 * This method is like `_.indexOf` except that it iterates over elements of |
4576 * |
5061 * `array` from right to left. |
4577 * var characters = [ |
5062 * |
4578 * { 'name': 'barney', 'blocked': false, 'employer': 'slate' }, |
5063 * @static |
4579 * { 'name': 'fred', 'blocked': true, 'employer': 'slate' }, |
5064 * @memberOf _ |
4580 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
5065 * @category Array |
4581 * ]; |
|
4582 * |
|
4583 * // using "_.pluck" callback shorthand |
|
4584 * _.pluck(_.last(characters, 'blocked'), 'name'); |
|
4585 * // => ['fred', 'pebbles'] |
|
4586 * |
|
4587 * // using "_.where" callback shorthand |
|
4588 * _.last(characters, { 'employer': 'na' }); |
|
4589 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] |
|
4590 */ |
|
4591 function last(array, callback, thisArg) { |
|
4592 var n = 0, |
|
4593 length = array ? array.length : 0; |
|
4594 |
|
4595 if (typeof callback != 'number' && callback != null) { |
|
4596 var index = length; |
|
4597 callback = lodash.createCallback(callback, thisArg, 3); |
|
4598 while (index-- && callback(array[index], index, array)) { |
|
4599 n++; |
|
4600 } |
|
4601 } else { |
|
4602 n = callback; |
|
4603 if (n == null || thisArg) { |
|
4604 return array ? array[length - 1] : undefined; |
|
4605 } |
|
4606 } |
|
4607 return slice(array, nativeMax(0, length - n)); |
|
4608 } |
|
4609 |
|
4610 /** |
|
4611 * Gets the index at which the last occurrence of `value` is found using strict |
|
4612 * equality for comparisons, i.e. `===`. If `fromIndex` is negative, it is used |
|
4613 * as the offset from the end of the collection. |
|
4614 * |
|
4615 * If a property name is provided for `callback` the created "_.pluck" style |
|
4616 * callback will return the property value of the given element. |
|
4617 * |
|
4618 * If an object is provided for `callback` the created "_.where" style callback |
|
4619 * will return `true` for elements that have the properties of the given object, |
|
4620 * else `false`. |
|
4621 * |
|
4622 * @static |
|
4623 * @memberOf _ |
|
4624 * @category Arrays |
|
4625 * @param {Array} array The array to search. |
5066 * @param {Array} array The array to search. |
4626 * @param {*} value The value to search for. |
5067 * @param {*} value The value to search for. |
4627 * @param {number} [fromIndex=array.length-1] The index to search from. |
5068 * @param {boolean|number} [fromIndex=array.length-1] The index to search from |
4628 * @returns {number} Returns the index of the matched value or `-1`. |
5069 * or `true` to perform a binary search on a sorted array. |
4629 * @example |
5070 * @returns {number} Returns the index of the matched value, else `-1`. |
4630 * |
5071 * @example |
4631 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2); |
5072 * |
4632 * // => 4 |
5073 * _.lastIndexOf([1, 2, 1, 2], 2); |
4633 * |
5074 * // => 3 |
4634 * _.lastIndexOf([1, 2, 3, 1, 2, 3], 2, 3); |
5075 * |
|
5076 * // using `fromIndex` |
|
5077 * _.lastIndexOf([1, 2, 1, 2], 2, 2); |
4635 * // => 1 |
5078 * // => 1 |
|
5079 * |
|
5080 * // performing a binary search |
|
5081 * _.lastIndexOf([1, 1, 2, 2], 2, true); |
|
5082 * // => 3 |
4636 */ |
5083 */ |
4637 function lastIndexOf(array, value, fromIndex) { |
5084 function lastIndexOf(array, value, fromIndex) { |
4638 var index = array ? array.length : 0; |
5085 var length = array ? array.length : 0; |
|
5086 if (!length) { |
|
5087 return -1; |
|
5088 } |
|
5089 var index = length; |
4639 if (typeof fromIndex == 'number') { |
5090 if (typeof fromIndex == 'number') { |
4640 index = (fromIndex < 0 ? nativeMax(0, index + fromIndex) : nativeMin(fromIndex, index - 1)) + 1; |
5091 index = (fromIndex < 0 ? nativeMax(length + fromIndex, 0) : nativeMin(fromIndex || 0, length - 1)) + 1; |
|
5092 } else if (fromIndex) { |
|
5093 index = binaryIndex(array, value, true) - 1; |
|
5094 var other = array[index]; |
|
5095 if (value === value ? (value === other) : (other !== other)) { |
|
5096 return index; |
|
5097 } |
|
5098 return -1; |
|
5099 } |
|
5100 if (value !== value) { |
|
5101 return indexOfNaN(array, index, true); |
4641 } |
5102 } |
4642 while (index--) { |
5103 while (index--) { |
4643 if (array[index] === value) { |
5104 if (array[index] === value) { |
4644 return index; |
5105 return index; |
4645 } |
5106 } |
4646 } |
5107 } |
4647 return -1; |
5108 return -1; |
4648 } |
5109 } |
4649 |
5110 |
4650 /** |
5111 /** |
4651 * Removes all provided values from the given array using strict equality for |
5112 * Removes all provided values from `array` using |
4652 * comparisons, i.e. `===`. |
5113 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
4653 * |
5114 * for equality comparisons. |
4654 * @static |
5115 * |
4655 * @memberOf _ |
5116 * **Note:** Unlike `_.without`, this method mutates `array`. |
4656 * @category Arrays |
5117 * |
|
5118 * @static |
|
5119 * @memberOf _ |
|
5120 * @category Array |
4657 * @param {Array} array The array to modify. |
5121 * @param {Array} array The array to modify. |
4658 * @param {...*} [value] The values to remove. |
5122 * @param {...*} [values] The values to remove. |
4659 * @returns {Array} Returns `array`. |
5123 * @returns {Array} Returns `array`. |
4660 * @example |
5124 * @example |
4661 * |
5125 * |
4662 * var array = [1, 2, 3, 1, 2, 3]; |
5126 * var array = [1, 2, 3, 1, 2, 3]; |
|
5127 * |
4663 * _.pull(array, 2, 3); |
5128 * _.pull(array, 2, 3); |
4664 * console.log(array); |
5129 * console.log(array); |
4665 * // => [1, 1] |
5130 * // => [1, 1] |
4666 */ |
5131 */ |
4667 function pull(array) { |
5132 function pull() { |
4668 var args = arguments, |
5133 var args = arguments, |
4669 argsIndex = 0, |
5134 array = args[0]; |
4670 argsLength = args.length, |
5135 |
4671 length = array ? array.length : 0; |
5136 if (!(array && array.length)) { |
4672 |
5137 return array; |
4673 while (++argsIndex < argsLength) { |
5138 } |
4674 var index = -1, |
5139 var index = 0, |
4675 value = args[argsIndex]; |
5140 indexOf = getIndexOf(), |
4676 while (++index < length) { |
5141 length = args.length; |
4677 if (array[index] === value) { |
5142 |
4678 splice.call(array, index--, 1); |
5143 while (++index < length) { |
4679 length--; |
5144 var fromIndex = 0, |
4680 } |
5145 value = args[index]; |
|
5146 |
|
5147 while ((fromIndex = indexOf(array, value, fromIndex)) > -1) { |
|
5148 splice.call(array, fromIndex, 1); |
4681 } |
5149 } |
4682 } |
5150 } |
4683 return array; |
5151 return array; |
4684 } |
5152 } |
4685 |
5153 |
4686 /** |
5154 /** |
4687 * Creates an array of numbers (positive and/or negative) progressing from |
5155 * Removes elements from `array` corresponding to the given indexes and returns |
4688 * `start` up to but not including `end`. If `start` is less than `stop` a |
5156 * an array of the removed elements. Indexes may be specified as an array of |
4689 * zero-length range is created unless a negative `step` is specified. |
5157 * indexes or as individual arguments. |
4690 * |
5158 * |
4691 * @static |
5159 * **Note:** Unlike `_.at`, this method mutates `array`. |
4692 * @memberOf _ |
5160 * |
4693 * @category Arrays |
5161 * @static |
4694 * @param {number} [start=0] The start of the range. |
5162 * @memberOf _ |
4695 * @param {number} end The end of the range. |
5163 * @category Array |
4696 * @param {number} [step=1] The value to increment or decrement by. |
5164 * @param {Array} array The array to modify. |
4697 * @returns {Array} Returns a new range array. |
5165 * @param {...(number|number[])} [indexes] The indexes of elements to remove, |
4698 * @example |
5166 * specified as individual indexes or arrays of indexes. |
4699 * |
5167 * @returns {Array} Returns the new array of removed elements. |
4700 * _.range(4); |
5168 * @example |
4701 * // => [0, 1, 2, 3] |
5169 * |
4702 * |
5170 * var array = [5, 10, 15, 20]; |
4703 * _.range(1, 5); |
5171 * var evens = _.pullAt(array, 1, 3); |
4704 * // => [1, 2, 3, 4] |
5172 * |
4705 * |
5173 * console.log(array); |
4706 * _.range(0, 20, 5); |
5174 * // => [5, 15] |
4707 * // => [0, 5, 10, 15] |
5175 * |
4708 * |
5176 * console.log(evens); |
4709 * _.range(0, -4, -1); |
5177 * // => [10, 20] |
4710 * // => [0, -1, -2, -3] |
5178 */ |
4711 * |
5179 var pullAt = restParam(function(array, indexes) { |
4712 * _.range(1, 4, 0); |
5180 indexes = baseFlatten(indexes); |
4713 * // => [1, 1, 1] |
5181 |
4714 * |
5182 var result = baseAt(array, indexes); |
4715 * _.range(0); |
5183 basePullAt(array, indexes.sort(baseCompareAscending)); |
4716 * // => [] |
5184 return result; |
4717 */ |
5185 }); |
4718 function range(start, end, step) { |
5186 |
4719 start = +start || 0; |
5187 /** |
4720 step = typeof step == 'number' ? step : (+step || 1); |
5188 * Removes all elements from `array` that `predicate` returns truthy for |
4721 |
5189 * and returns an array of the removed elements. The predicate is bound to |
4722 if (end == null) { |
5190 * `thisArg` and invoked with three arguments: (value, index, array). |
4723 end = start; |
5191 * |
4724 start = 0; |
5192 * If a property name is provided for `predicate` the created `_.property` |
4725 } |
5193 * style callback returns the property value of the given element. |
4726 // use `Array(length)` so engines like Chakra and V8 avoid slower modes |
5194 * |
4727 // http://youtu.be/XAqIpGU8ZZk#t=17m25s |
5195 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
5196 * style callback returns `true` for elements that have a matching property |
|
5197 * value, else `false`. |
|
5198 * |
|
5199 * If an object is provided for `predicate` the created `_.matches` style |
|
5200 * callback returns `true` for elements that have the properties of the given |
|
5201 * object, else `false`. |
|
5202 * |
|
5203 * **Note:** Unlike `_.filter`, this method mutates `array`. |
|
5204 * |
|
5205 * @static |
|
5206 * @memberOf _ |
|
5207 * @category Array |
|
5208 * @param {Array} array The array to modify. |
|
5209 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
5210 * per iteration. |
|
5211 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
5212 * @returns {Array} Returns the new array of removed elements. |
|
5213 * @example |
|
5214 * |
|
5215 * var array = [1, 2, 3, 4]; |
|
5216 * var evens = _.remove(array, function(n) { |
|
5217 * return n % 2 == 0; |
|
5218 * }); |
|
5219 * |
|
5220 * console.log(array); |
|
5221 * // => [1, 3] |
|
5222 * |
|
5223 * console.log(evens); |
|
5224 * // => [2, 4] |
|
5225 */ |
|
5226 function remove(array, predicate, thisArg) { |
|
5227 var result = []; |
|
5228 if (!(array && array.length)) { |
|
5229 return result; |
|
5230 } |
4728 var index = -1, |
5231 var index = -1, |
4729 length = nativeMax(0, ceil((end - start) / (step || 1))), |
5232 indexes = [], |
4730 result = Array(length); |
5233 length = array.length; |
4731 |
5234 |
4732 while (++index < length) { |
5235 predicate = getCallback(predicate, thisArg, 3); |
4733 result[index] = start; |
|
4734 start += step; |
|
4735 } |
|
4736 return result; |
|
4737 } |
|
4738 |
|
4739 /** |
|
4740 * Removes all elements from an array that the callback returns truey for |
|
4741 * and returns an array of removed elements. The callback is bound to `thisArg` |
|
4742 * and invoked with three arguments; (value, index, array). |
|
4743 * |
|
4744 * If a property name is provided for `callback` the created "_.pluck" style |
|
4745 * callback will return the property value of the given element. |
|
4746 * |
|
4747 * If an object is provided for `callback` the created "_.where" style callback |
|
4748 * will return `true` for elements that have the properties of the given object, |
|
4749 * else `false`. |
|
4750 * |
|
4751 * @static |
|
4752 * @memberOf _ |
|
4753 * @category Arrays |
|
4754 * @param {Array} array The array to modify. |
|
4755 * @param {Function|Object|string} [callback=identity] The function called |
|
4756 * per iteration. If a property name or object is provided it will be used |
|
4757 * to create a "_.pluck" or "_.where" style callback, respectively. |
|
4758 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4759 * @returns {Array} Returns a new array of removed elements. |
|
4760 * @example |
|
4761 * |
|
4762 * var array = [1, 2, 3, 4, 5, 6]; |
|
4763 * var evens = _.remove(array, function(num) { return num % 2 == 0; }); |
|
4764 * |
|
4765 * console.log(array); |
|
4766 * // => [1, 3, 5] |
|
4767 * |
|
4768 * console.log(evens); |
|
4769 * // => [2, 4, 6] |
|
4770 */ |
|
4771 function remove(array, callback, thisArg) { |
|
4772 var index = -1, |
|
4773 length = array ? array.length : 0, |
|
4774 result = []; |
|
4775 |
|
4776 callback = lodash.createCallback(callback, thisArg, 3); |
|
4777 while (++index < length) { |
5236 while (++index < length) { |
4778 var value = array[index]; |
5237 var value = array[index]; |
4779 if (callback(value, index, array)) { |
5238 if (predicate(value, index, array)) { |
4780 result.push(value); |
5239 result.push(value); |
4781 splice.call(array, index--, 1); |
5240 indexes.push(index); |
4782 length--; |
5241 } |
4783 } |
5242 } |
4784 } |
5243 basePullAt(array, indexes); |
4785 return result; |
5244 return result; |
4786 } |
5245 } |
4787 |
5246 |
4788 /** |
5247 /** |
4789 * The opposite of `_.initial` this method gets all but the first element or |
5248 * Gets all but the first element of `array`. |
4790 * first `n` elements of an array. If a callback function is provided elements |
5249 * |
4791 * at the beginning of the array are excluded from the result as long as the |
5250 * @static |
4792 * callback returns truey. The callback is bound to `thisArg` and invoked |
5251 * @memberOf _ |
4793 * with three arguments; (value, index, array). |
5252 * @alias tail |
4794 * |
5253 * @category Array |
4795 * If a property name is provided for `callback` the created "_.pluck" style |
|
4796 * callback will return the property value of the given element. |
|
4797 * |
|
4798 * If an object is provided for `callback` the created "_.where" style callback |
|
4799 * will return `true` for elements that have the properties of the given object, |
|
4800 * else `false`. |
|
4801 * |
|
4802 * @static |
|
4803 * @memberOf _ |
|
4804 * @alias drop, tail |
|
4805 * @category Arrays |
|
4806 * @param {Array} array The array to query. |
5254 * @param {Array} array The array to query. |
4807 * @param {Function|Object|number|string} [callback=1] The function called |
5255 * @returns {Array} Returns the slice of `array`. |
4808 * per element or the number of elements to exclude. If a property name or |
|
4809 * object is provided it will be used to create a "_.pluck" or "_.where" |
|
4810 * style callback, respectively. |
|
4811 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4812 * @returns {Array} Returns a slice of `array`. |
|
4813 * @example |
5256 * @example |
4814 * |
5257 * |
4815 * _.rest([1, 2, 3]); |
5258 * _.rest([1, 2, 3]); |
4816 * // => [2, 3] |
5259 * // => [2, 3] |
4817 * |
5260 */ |
4818 * _.rest([1, 2, 3], 2); |
5261 function rest(array) { |
4819 * // => [3] |
5262 return drop(array, 1); |
4820 * |
5263 } |
4821 * _.rest([1, 2, 3], function(num) { |
5264 |
4822 * return num < 3; |
5265 /** |
4823 * }); |
5266 * Creates a slice of `array` from `start` up to, but not including, `end`. |
4824 * // => [3] |
5267 * |
4825 * |
5268 * **Note:** This method is used instead of `Array#slice` to support node |
4826 * var characters = [ |
5269 * lists in IE < 9 and to ensure dense arrays are returned. |
4827 * { 'name': 'barney', 'blocked': true, 'employer': 'slate' }, |
5270 * |
4828 * { 'name': 'fred', 'blocked': false, 'employer': 'slate' }, |
5271 * @static |
4829 * { 'name': 'pebbles', 'blocked': true, 'employer': 'na' } |
5272 * @memberOf _ |
4830 * ]; |
5273 * @category Array |
4831 * |
5274 * @param {Array} array The array to slice. |
4832 * // using "_.pluck" callback shorthand |
5275 * @param {number} [start=0] The start position. |
4833 * _.pluck(_.rest(characters, 'blocked'), 'name'); |
5276 * @param {number} [end=array.length] The end position. |
4834 * // => ['fred', 'pebbles'] |
5277 * @returns {Array} Returns the slice of `array`. |
4835 * |
5278 */ |
4836 * // using "_.where" callback shorthand |
5279 function slice(array, start, end) { |
4837 * _.rest(characters, { 'employer': 'slate' }); |
5280 var length = array ? array.length : 0; |
4838 * // => [{ 'name': 'pebbles', 'blocked': true, 'employer': 'na' }] |
5281 if (!length) { |
4839 */ |
5282 return []; |
4840 function rest(array, callback, thisArg) { |
5283 } |
4841 if (typeof callback != 'number' && callback != null) { |
5284 if (end && typeof end != 'number' && isIterateeCall(array, start, end)) { |
4842 var n = 0, |
5285 start = 0; |
4843 index = -1, |
5286 end = length; |
4844 length = array ? array.length : 0; |
5287 } |
4845 |
5288 return baseSlice(array, start, end); |
4846 callback = lodash.createCallback(callback, thisArg, 3); |
5289 } |
4847 while (++index < length && callback(array[index], index, array)) { |
5290 |
4848 n++; |
5291 /** |
4849 } |
5292 * Uses a binary search to determine the lowest index at which `value` should |
4850 } else { |
5293 * be inserted into `array` in order to maintain its sort order. If an iteratee |
4851 n = (callback == null || thisArg) ? 1 : nativeMax(0, callback); |
5294 * function is provided it's invoked for `value` and each element of `array` |
4852 } |
5295 * to compute their sort ranking. The iteratee is bound to `thisArg` and |
4853 return slice(array, n); |
5296 * invoked with one argument; (value). |
4854 } |
5297 * |
4855 |
5298 * If a property name is provided for `iteratee` the created `_.property` |
4856 /** |
5299 * style callback returns the property value of the given element. |
4857 * Uses a binary search to determine the smallest index at which a value |
5300 * |
4858 * should be inserted into a given sorted array in order to maintain the sort |
5301 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
4859 * order of the array. If a callback is provided it will be executed for |
5302 * style callback returns `true` for elements that have a matching property |
4860 * `value` and each element of `array` to compute their sort ranking. The |
5303 * value, else `false`. |
4861 * callback is bound to `thisArg` and invoked with one argument; (value). |
5304 * |
4862 * |
5305 * If an object is provided for `iteratee` the created `_.matches` style |
4863 * If a property name is provided for `callback` the created "_.pluck" style |
5306 * callback returns `true` for elements that have the properties of the given |
4864 * callback will return the property value of the given element. |
5307 * object, else `false`. |
4865 * |
5308 * |
4866 * If an object is provided for `callback` the created "_.where" style callback |
5309 * @static |
4867 * will return `true` for elements that have the properties of the given object, |
5310 * @memberOf _ |
4868 * else `false`. |
5311 * @category Array |
4869 * |
5312 * @param {Array} array The sorted array to inspect. |
4870 * @static |
|
4871 * @memberOf _ |
|
4872 * @category Arrays |
|
4873 * @param {Array} array The array to inspect. |
|
4874 * @param {*} value The value to evaluate. |
5313 * @param {*} value The value to evaluate. |
4875 * @param {Function|Object|string} [callback=identity] The function called |
5314 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
4876 * per iteration. If a property name or object is provided it will be used |
5315 * per iteration. |
4877 * to create a "_.pluck" or "_.where" style callback, respectively. |
5316 * @param {*} [thisArg] The `this` binding of `iteratee`. |
4878 * @param {*} [thisArg] The `this` binding of `callback`. |
|
4879 * @returns {number} Returns the index at which `value` should be inserted |
5317 * @returns {number} Returns the index at which `value` should be inserted |
4880 * into `array`. |
5318 * into `array`. |
4881 * @example |
5319 * @example |
4882 * |
5320 * |
4883 * _.sortedIndex([20, 30, 50], 40); |
5321 * _.sortedIndex([30, 50], 40); |
|
5322 * // => 1 |
|
5323 * |
|
5324 * _.sortedIndex([4, 4, 5, 5], 5); |
4884 * // => 2 |
5325 * // => 2 |
4885 * |
5326 * |
4886 * // using "_.pluck" callback shorthand |
5327 * var dict = { 'data': { 'thirty': 30, 'forty': 40, 'fifty': 50 } }; |
4887 * _.sortedIndex([{ 'x': 20 }, { 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); |
5328 * |
4888 * // => 2 |
5329 * // using an iteratee function |
4889 * |
5330 * _.sortedIndex(['thirty', 'fifty'], 'forty', function(word) { |
4890 * var dict = { |
5331 * return this.data[word]; |
4891 * 'wordToNumber': { 'twenty': 20, 'thirty': 30, 'fourty': 40, 'fifty': 50 } |
5332 * }, dict); |
4892 * }; |
5333 * // => 1 |
4893 * |
5334 * |
4894 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { |
5335 * // using the `_.property` callback shorthand |
4895 * return dict.wordToNumber[word]; |
5336 * _.sortedIndex([{ 'x': 30 }, { 'x': 50 }], { 'x': 40 }, 'x'); |
|
5337 * // => 1 |
|
5338 */ |
|
5339 var sortedIndex = createSortedIndex(); |
|
5340 |
|
5341 /** |
|
5342 * This method is like `_.sortedIndex` except that it returns the highest |
|
5343 * index at which `value` should be inserted into `array` in order to |
|
5344 * maintain its sort order. |
|
5345 * |
|
5346 * @static |
|
5347 * @memberOf _ |
|
5348 * @category Array |
|
5349 * @param {Array} array The sorted array to inspect. |
|
5350 * @param {*} value The value to evaluate. |
|
5351 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
5352 * per iteration. |
|
5353 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
5354 * @returns {number} Returns the index at which `value` should be inserted |
|
5355 * into `array`. |
|
5356 * @example |
|
5357 * |
|
5358 * _.sortedLastIndex([4, 4, 5, 5], 5); |
|
5359 * // => 4 |
|
5360 */ |
|
5361 var sortedLastIndex = createSortedIndex(true); |
|
5362 |
|
5363 /** |
|
5364 * Creates a slice of `array` with `n` elements taken from the beginning. |
|
5365 * |
|
5366 * @static |
|
5367 * @memberOf _ |
|
5368 * @category Array |
|
5369 * @param {Array} array The array to query. |
|
5370 * @param {number} [n=1] The number of elements to take. |
|
5371 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
5372 * @returns {Array} Returns the slice of `array`. |
|
5373 * @example |
|
5374 * |
|
5375 * _.take([1, 2, 3]); |
|
5376 * // => [1] |
|
5377 * |
|
5378 * _.take([1, 2, 3], 2); |
|
5379 * // => [1, 2] |
|
5380 * |
|
5381 * _.take([1, 2, 3], 5); |
|
5382 * // => [1, 2, 3] |
|
5383 * |
|
5384 * _.take([1, 2, 3], 0); |
|
5385 * // => [] |
|
5386 */ |
|
5387 function take(array, n, guard) { |
|
5388 var length = array ? array.length : 0; |
|
5389 if (!length) { |
|
5390 return []; |
|
5391 } |
|
5392 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
|
5393 n = 1; |
|
5394 } |
|
5395 return baseSlice(array, 0, n < 0 ? 0 : n); |
|
5396 } |
|
5397 |
|
5398 /** |
|
5399 * Creates a slice of `array` with `n` elements taken from the end. |
|
5400 * |
|
5401 * @static |
|
5402 * @memberOf _ |
|
5403 * @category Array |
|
5404 * @param {Array} array The array to query. |
|
5405 * @param {number} [n=1] The number of elements to take. |
|
5406 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
5407 * @returns {Array} Returns the slice of `array`. |
|
5408 * @example |
|
5409 * |
|
5410 * _.takeRight([1, 2, 3]); |
|
5411 * // => [3] |
|
5412 * |
|
5413 * _.takeRight([1, 2, 3], 2); |
|
5414 * // => [2, 3] |
|
5415 * |
|
5416 * _.takeRight([1, 2, 3], 5); |
|
5417 * // => [1, 2, 3] |
|
5418 * |
|
5419 * _.takeRight([1, 2, 3], 0); |
|
5420 * // => [] |
|
5421 */ |
|
5422 function takeRight(array, n, guard) { |
|
5423 var length = array ? array.length : 0; |
|
5424 if (!length) { |
|
5425 return []; |
|
5426 } |
|
5427 if (guard ? isIterateeCall(array, n, guard) : n == null) { |
|
5428 n = 1; |
|
5429 } |
|
5430 n = length - (+n || 0); |
|
5431 return baseSlice(array, n < 0 ? 0 : n); |
|
5432 } |
|
5433 |
|
5434 /** |
|
5435 * Creates a slice of `array` with elements taken from the end. Elements are |
|
5436 * taken until `predicate` returns falsey. The predicate is bound to `thisArg` |
|
5437 * and invoked with three arguments: (value, index, array). |
|
5438 * |
|
5439 * If a property name is provided for `predicate` the created `_.property` |
|
5440 * style callback returns the property value of the given element. |
|
5441 * |
|
5442 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
5443 * style callback returns `true` for elements that have a matching property |
|
5444 * value, else `false`. |
|
5445 * |
|
5446 * If an object is provided for `predicate` the created `_.matches` style |
|
5447 * callback returns `true` for elements that have the properties of the given |
|
5448 * object, else `false`. |
|
5449 * |
|
5450 * @static |
|
5451 * @memberOf _ |
|
5452 * @category Array |
|
5453 * @param {Array} array The array to query. |
|
5454 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
5455 * per iteration. |
|
5456 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
5457 * @returns {Array} Returns the slice of `array`. |
|
5458 * @example |
|
5459 * |
|
5460 * _.takeRightWhile([1, 2, 3], function(n) { |
|
5461 * return n > 1; |
4896 * }); |
5462 * }); |
4897 * // => 2 |
5463 * // => [2, 3] |
4898 * |
5464 * |
4899 * _.sortedIndex(['twenty', 'thirty', 'fifty'], 'fourty', function(word) { |
5465 * var users = [ |
4900 * return this.wordToNumber[word]; |
5466 * { 'user': 'barney', 'active': true }, |
4901 * }, dict); |
5467 * { 'user': 'fred', 'active': false }, |
4902 * // => 2 |
5468 * { 'user': 'pebbles', 'active': false } |
4903 */ |
5469 * ]; |
4904 function sortedIndex(array, value, callback, thisArg) { |
5470 * |
4905 var low = 0, |
5471 * // using the `_.matches` callback shorthand |
4906 high = array ? array.length : low; |
5472 * _.pluck(_.takeRightWhile(users, { 'user': 'pebbles', 'active': false }), 'user'); |
4907 |
5473 * // => ['pebbles'] |
4908 // explicitly reference `identity` for better inlining in Firefox |
5474 * |
4909 callback = callback ? lodash.createCallback(callback, thisArg, 1) : identity; |
5475 * // using the `_.matchesProperty` callback shorthand |
4910 value = callback(value); |
5476 * _.pluck(_.takeRightWhile(users, 'active', false), 'user'); |
4911 |
5477 * // => ['fred', 'pebbles'] |
4912 while (low < high) { |
5478 * |
4913 var mid = (low + high) >>> 1; |
5479 * // using the `_.property` callback shorthand |
4914 (callback(array[mid]) < value) |
5480 * _.pluck(_.takeRightWhile(users, 'active'), 'user'); |
4915 ? low = mid + 1 |
5481 * // => [] |
4916 : high = mid; |
5482 */ |
4917 } |
5483 function takeRightWhile(array, predicate, thisArg) { |
4918 return low; |
5484 return (array && array.length) |
4919 } |
5485 ? baseWhile(array, getCallback(predicate, thisArg, 3), false, true) |
4920 |
5486 : []; |
4921 /** |
5487 } |
4922 * Creates an array of unique values, in order, of the provided arrays using |
5488 |
4923 * strict equality for comparisons, i.e. `===`. |
5489 /** |
4924 * |
5490 * Creates a slice of `array` with elements taken from the beginning. Elements |
4925 * @static |
5491 * are taken until `predicate` returns falsey. The predicate is bound to |
4926 * @memberOf _ |
5492 * `thisArg` and invoked with three arguments: (value, index, array). |
4927 * @category Arrays |
5493 * |
4928 * @param {...Array} [array] The arrays to inspect. |
5494 * If a property name is provided for `predicate` the created `_.property` |
4929 * @returns {Array} Returns an array of combined values. |
5495 * style callback returns the property value of the given element. |
4930 * @example |
5496 * |
4931 * |
5497 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
4932 * _.union([1, 2, 3], [5, 2, 1, 4], [2, 1]); |
5498 * style callback returns `true` for elements that have a matching property |
4933 * // => [1, 2, 3, 5, 4] |
5499 * value, else `false`. |
4934 */ |
5500 * |
4935 function union() { |
5501 * If an object is provided for `predicate` the created `_.matches` style |
4936 return baseUniq(baseFlatten(arguments, true, true)); |
5502 * callback returns `true` for elements that have the properties of the given |
4937 } |
5503 * object, else `false`. |
4938 |
5504 * |
4939 /** |
5505 * @static |
4940 * Creates a duplicate-value-free version of an array using strict equality |
5506 * @memberOf _ |
4941 * for comparisons, i.e. `===`. If the array is sorted, providing |
5507 * @category Array |
4942 * `true` for `isSorted` will use a faster algorithm. If a callback is provided |
5508 * @param {Array} array The array to query. |
4943 * each element of `array` is passed through the callback before uniqueness |
5509 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
4944 * is computed. The callback is bound to `thisArg` and invoked with three |
5510 * per iteration. |
4945 * arguments; (value, index, array). |
5511 * @param {*} [thisArg] The `this` binding of `predicate`. |
4946 * |
5512 * @returns {Array} Returns the slice of `array`. |
4947 * If a property name is provided for `callback` the created "_.pluck" style |
5513 * @example |
4948 * callback will return the property value of the given element. |
5514 * |
4949 * |
5515 * _.takeWhile([1, 2, 3], function(n) { |
4950 * If an object is provided for `callback` the created "_.where" style callback |
5516 * return n < 3; |
4951 * will return `true` for elements that have the properties of the given object, |
5517 * }); |
4952 * else `false`. |
5518 * // => [1, 2] |
|
5519 * |
|
5520 * var users = [ |
|
5521 * { 'user': 'barney', 'active': false }, |
|
5522 * { 'user': 'fred', 'active': false}, |
|
5523 * { 'user': 'pebbles', 'active': true } |
|
5524 * ]; |
|
5525 * |
|
5526 * // using the `_.matches` callback shorthand |
|
5527 * _.pluck(_.takeWhile(users, { 'user': 'barney', 'active': false }), 'user'); |
|
5528 * // => ['barney'] |
|
5529 * |
|
5530 * // using the `_.matchesProperty` callback shorthand |
|
5531 * _.pluck(_.takeWhile(users, 'active', false), 'user'); |
|
5532 * // => ['barney', 'fred'] |
|
5533 * |
|
5534 * // using the `_.property` callback shorthand |
|
5535 * _.pluck(_.takeWhile(users, 'active'), 'user'); |
|
5536 * // => [] |
|
5537 */ |
|
5538 function takeWhile(array, predicate, thisArg) { |
|
5539 return (array && array.length) |
|
5540 ? baseWhile(array, getCallback(predicate, thisArg, 3)) |
|
5541 : []; |
|
5542 } |
|
5543 |
|
5544 /** |
|
5545 * Creates an array of unique values, in order, from all of the provided arrays |
|
5546 * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
|
5547 * for equality comparisons. |
|
5548 * |
|
5549 * @static |
|
5550 * @memberOf _ |
|
5551 * @category Array |
|
5552 * @param {...Array} [arrays] The arrays to inspect. |
|
5553 * @returns {Array} Returns the new array of combined values. |
|
5554 * @example |
|
5555 * |
|
5556 * _.union([1, 2], [4, 2], [2, 1]); |
|
5557 * // => [1, 2, 4] |
|
5558 */ |
|
5559 var union = restParam(function(arrays) { |
|
5560 return baseUniq(baseFlatten(arrays, false, true)); |
|
5561 }); |
|
5562 |
|
5563 /** |
|
5564 * Creates a duplicate-free version of an array, using |
|
5565 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
|
5566 * for equality comparisons, in which only the first occurence of each element |
|
5567 * is kept. Providing `true` for `isSorted` performs a faster search algorithm |
|
5568 * for sorted arrays. If an iteratee function is provided it's invoked for |
|
5569 * each element in the array to generate the criterion by which uniqueness |
|
5570 * is computed. The `iteratee` is bound to `thisArg` and invoked with three |
|
5571 * arguments: (value, index, array). |
|
5572 * |
|
5573 * If a property name is provided for `iteratee` the created `_.property` |
|
5574 * style callback returns the property value of the given element. |
|
5575 * |
|
5576 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
5577 * style callback returns `true` for elements that have a matching property |
|
5578 * value, else `false`. |
|
5579 * |
|
5580 * If an object is provided for `iteratee` the created `_.matches` style |
|
5581 * callback returns `true` for elements that have the properties of the given |
|
5582 * object, else `false`. |
4953 * |
5583 * |
4954 * @static |
5584 * @static |
4955 * @memberOf _ |
5585 * @memberOf _ |
4956 * @alias unique |
5586 * @alias unique |
4957 * @category Arrays |
5587 * @category Array |
4958 * @param {Array} array The array to process. |
5588 * @param {Array} array The array to inspect. |
4959 * @param {boolean} [isSorted=false] A flag to indicate that `array` is sorted. |
5589 * @param {boolean} [isSorted] Specify the array is sorted. |
4960 * @param {Function|Object|string} [callback=identity] The function called |
5590 * @param {Function|Object|string} [iteratee] The function invoked per iteration. |
4961 * per iteration. If a property name or object is provided it will be used |
5591 * @param {*} [thisArg] The `this` binding of `iteratee`. |
4962 * to create a "_.pluck" or "_.where" style callback, respectively. |
5592 * @returns {Array} Returns the new duplicate-value-free array. |
4963 * @param {*} [thisArg] The `this` binding of `callback`. |
5593 * @example |
4964 * @returns {Array} Returns a duplicate-value-free array. |
5594 * |
4965 * @example |
5595 * _.uniq([2, 1, 2]); |
4966 * |
5596 * // => [2, 1] |
4967 * _.uniq([1, 2, 1, 3, 1]); |
5597 * |
4968 * // => [1, 2, 3] |
5598 * // using `isSorted` |
4969 * |
5599 * _.uniq([1, 1, 2], true); |
4970 * _.uniq([1, 1, 2, 2, 3], true); |
5600 * // => [1, 2] |
4971 * // => [1, 2, 3] |
5601 * |
4972 * |
5602 * // using an iteratee function |
4973 * _.uniq(['A', 'b', 'C', 'a', 'B', 'c'], function(letter) { return letter.toLowerCase(); }); |
5603 * _.uniq([1, 2.5, 1.5, 2], function(n) { |
4974 * // => ['A', 'b', 'C'] |
5604 * return this.floor(n); |
4975 * |
5605 * }, Math); |
4976 * _.uniq([1, 2.5, 3, 1.5, 2, 3.5], function(num) { return this.floor(num); }, Math); |
5606 * // => [1, 2.5] |
4977 * // => [1, 2.5, 3] |
5607 * |
4978 * |
5608 * // using the `_.property` callback shorthand |
4979 * // using "_.pluck" callback shorthand |
|
4980 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
5609 * _.uniq([{ 'x': 1 }, { 'x': 2 }, { 'x': 1 }], 'x'); |
4981 * // => [{ 'x': 1 }, { 'x': 2 }] |
5610 * // => [{ 'x': 1 }, { 'x': 2 }] |
4982 */ |
5611 */ |
4983 function uniq(array, isSorted, callback, thisArg) { |
5612 function uniq(array, isSorted, iteratee, thisArg) { |
4984 // juggle arguments |
5613 var length = array ? array.length : 0; |
4985 if (typeof isSorted != 'boolean' && isSorted != null) { |
5614 if (!length) { |
4986 thisArg = callback; |
5615 return []; |
4987 callback = (typeof isSorted != 'function' && thisArg && thisArg[isSorted] === array) ? null : isSorted; |
5616 } |
|
5617 if (isSorted != null && typeof isSorted != 'boolean') { |
|
5618 thisArg = iteratee; |
|
5619 iteratee = isIterateeCall(array, isSorted, thisArg) ? undefined : isSorted; |
4988 isSorted = false; |
5620 isSorted = false; |
4989 } |
5621 } |
4990 if (callback != null) { |
5622 var callback = getCallback(); |
4991 callback = lodash.createCallback(callback, thisArg, 3); |
5623 if (!(iteratee == null && callback === baseCallback)) { |
4992 } |
5624 iteratee = callback(iteratee, thisArg, 3); |
4993 return baseUniq(array, isSorted, callback); |
5625 } |
4994 } |
5626 return (isSorted && getIndexOf() === baseIndexOf) |
4995 |
5627 ? sortedUniq(array, iteratee) |
4996 /** |
5628 : baseUniq(array, iteratee); |
4997 * Creates an array excluding all provided values using strict equality for |
5629 } |
4998 * comparisons, i.e. `===`. |
5630 |
4999 * |
5631 /** |
5000 * @static |
5632 * This method is like `_.zip` except that it accepts an array of grouped |
5001 * @memberOf _ |
5633 * elements and creates an array regrouping the elements to their pre-zip |
5002 * @category Arrays |
5634 * configuration. |
|
5635 * |
|
5636 * @static |
|
5637 * @memberOf _ |
|
5638 * @category Array |
|
5639 * @param {Array} array The array of grouped elements to process. |
|
5640 * @returns {Array} Returns the new array of regrouped elements. |
|
5641 * @example |
|
5642 * |
|
5643 * var zipped = _.zip(['fred', 'barney'], [30, 40], [true, false]); |
|
5644 * // => [['fred', 30, true], ['barney', 40, false]] |
|
5645 * |
|
5646 * _.unzip(zipped); |
|
5647 * // => [['fred', 'barney'], [30, 40], [true, false]] |
|
5648 */ |
|
5649 function unzip(array) { |
|
5650 if (!(array && array.length)) { |
|
5651 return []; |
|
5652 } |
|
5653 var index = -1, |
|
5654 length = 0; |
|
5655 |
|
5656 array = arrayFilter(array, function(group) { |
|
5657 if (isArrayLike(group)) { |
|
5658 length = nativeMax(group.length, length); |
|
5659 return true; |
|
5660 } |
|
5661 }); |
|
5662 var result = Array(length); |
|
5663 while (++index < length) { |
|
5664 result[index] = arrayMap(array, baseProperty(index)); |
|
5665 } |
|
5666 return result; |
|
5667 } |
|
5668 |
|
5669 /** |
|
5670 * This method is like `_.unzip` except that it accepts an iteratee to specify |
|
5671 * how regrouped values should be combined. The `iteratee` is bound to `thisArg` |
|
5672 * and invoked with four arguments: (accumulator, value, index, group). |
|
5673 * |
|
5674 * @static |
|
5675 * @memberOf _ |
|
5676 * @category Array |
|
5677 * @param {Array} array The array of grouped elements to process. |
|
5678 * @param {Function} [iteratee] The function to combine regrouped values. |
|
5679 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
5680 * @returns {Array} Returns the new array of regrouped elements. |
|
5681 * @example |
|
5682 * |
|
5683 * var zipped = _.zip([1, 2], [10, 20], [100, 200]); |
|
5684 * // => [[1, 10, 100], [2, 20, 200]] |
|
5685 * |
|
5686 * _.unzipWith(zipped, _.add); |
|
5687 * // => [3, 30, 300] |
|
5688 */ |
|
5689 function unzipWith(array, iteratee, thisArg) { |
|
5690 var length = array ? array.length : 0; |
|
5691 if (!length) { |
|
5692 return []; |
|
5693 } |
|
5694 var result = unzip(array); |
|
5695 if (iteratee == null) { |
|
5696 return result; |
|
5697 } |
|
5698 iteratee = bindCallback(iteratee, thisArg, 4); |
|
5699 return arrayMap(result, function(group) { |
|
5700 return arrayReduce(group, iteratee, undefined, true); |
|
5701 }); |
|
5702 } |
|
5703 |
|
5704 /** |
|
5705 * Creates an array excluding all provided values using |
|
5706 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
|
5707 * for equality comparisons. |
|
5708 * |
|
5709 * @static |
|
5710 * @memberOf _ |
|
5711 * @category Array |
5003 * @param {Array} array The array to filter. |
5712 * @param {Array} array The array to filter. |
5004 * @param {...*} [value] The values to exclude. |
5713 * @param {...*} [values] The values to exclude. |
5005 * @returns {Array} Returns a new array of filtered values. |
5714 * @returns {Array} Returns the new array of filtered values. |
5006 * @example |
5715 * @example |
5007 * |
5716 * |
5008 * _.without([1, 2, 1, 0, 3, 1, 4], 0, 1); |
5717 * _.without([1, 2, 1, 3], 1, 2); |
5009 * // => [2, 3, 4] |
5718 * // => [3] |
5010 */ |
5719 */ |
5011 function without(array) { |
5720 var without = restParam(function(array, values) { |
5012 return baseDifference(array, slice(arguments, 1)); |
5721 return isArrayLike(array) |
5013 } |
5722 ? baseDifference(array, values) |
5014 |
5723 : []; |
5015 /** |
5724 }); |
5016 * Creates an array that is the symmetric difference of the provided arrays. |
5725 |
5017 * See http://en.wikipedia.org/wiki/Symmetric_difference. |
5726 /** |
5018 * |
5727 * Creates an array of unique values that is the [symmetric difference](https://en.wikipedia.org/wiki/Symmetric_difference) |
5019 * @static |
5728 * of the provided arrays. |
5020 * @memberOf _ |
5729 * |
5021 * @category Arrays |
5730 * @static |
5022 * @param {...Array} [array] The arrays to inspect. |
5731 * @memberOf _ |
5023 * @returns {Array} Returns an array of values. |
5732 * @category Array |
5024 * @example |
5733 * @param {...Array} [arrays] The arrays to inspect. |
5025 * |
5734 * @returns {Array} Returns the new array of values. |
5026 * _.xor([1, 2, 3], [5, 2, 1, 4]); |
5735 * @example |
5027 * // => [3, 5, 4] |
5736 * |
5028 * |
5737 * _.xor([1, 2], [4, 2]); |
5029 * _.xor([1, 2, 5], [2, 3, 5], [3, 4, 5]); |
5738 * // => [1, 4] |
5030 * // => [1, 4, 5] |
|
5031 */ |
5739 */ |
5032 function xor() { |
5740 function xor() { |
5033 var index = -1, |
5741 var index = -1, |
5034 length = arguments.length; |
5742 length = arguments.length; |
5035 |
5743 |
5036 while (++index < length) { |
5744 while (++index < length) { |
5037 var array = arguments[index]; |
5745 var array = arguments[index]; |
5038 if (isArray(array) || isArguments(array)) { |
5746 if (isArrayLike(array)) { |
5039 var result = result |
5747 var result = result |
5040 ? baseUniq(baseDifference(result, array).concat(baseDifference(array, result))) |
5748 ? arrayPush(baseDifference(result, array), baseDifference(array, result)) |
5041 : array; |
5749 : array; |
5042 } |
5750 } |
5043 } |
5751 } |
5044 return result || []; |
5752 return result ? baseUniq(result) : []; |
5045 } |
5753 } |
5046 |
5754 |
5047 /** |
5755 /** |
5048 * Creates an array of grouped elements, the first of which contains the first |
5756 * Creates an array of grouped elements, the first of which contains the first |
5049 * elements of the given arrays, the second of which contains the second |
5757 * elements of the given arrays, the second of which contains the second elements |
5050 * elements of the given arrays, and so on. |
5758 * of the given arrays, and so on. |
5051 * |
5759 * |
5052 * @static |
5760 * @static |
5053 * @memberOf _ |
5761 * @memberOf _ |
5054 * @alias unzip |
5762 * @category Array |
5055 * @category Arrays |
5763 * @param {...Array} [arrays] The arrays to process. |
5056 * @param {...Array} [array] Arrays to process. |
5764 * @returns {Array} Returns the new array of grouped elements. |
5057 * @returns {Array} Returns a new array of grouped elements. |
|
5058 * @example |
5765 * @example |
5059 * |
5766 * |
5060 * _.zip(['fred', 'barney'], [30, 40], [true, false]); |
5767 * _.zip(['fred', 'barney'], [30, 40], [true, false]); |
5061 * // => [['fred', 30, true], ['barney', 40, false]] |
5768 * // => [['fred', 30, true], ['barney', 40, false]] |
5062 */ |
5769 */ |
5063 function zip() { |
5770 var zip = restParam(unzip); |
5064 var array = arguments.length > 1 ? arguments : arguments[0], |
5771 |
5065 index = -1, |
5772 /** |
5066 length = array ? max(pluck(array, 'length')) : 0, |
5773 * The inverse of `_.pairs`; this method returns an object composed from arrays |
5067 result = Array(length < 0 ? 0 : length); |
5774 * of property names and values. Provide either a single two dimensional array, |
5068 |
5775 * e.g. `[[key1, value1], [key2, value2]]` or two arrays, one of property names |
5069 while (++index < length) { |
5776 * and one of corresponding values. |
5070 result[index] = pluck(array, index); |
|
5071 } |
|
5072 return result; |
|
5073 } |
|
5074 |
|
5075 /** |
|
5076 * Creates an object composed from arrays of `keys` and `values`. Provide |
|
5077 * either a single two dimensional array, i.e. `[[key1, value1], [key2, value2]]` |
|
5078 * or two arrays, one of `keys` and one of corresponding `values`. |
|
5079 * |
5777 * |
5080 * @static |
5778 * @static |
5081 * @memberOf _ |
5779 * @memberOf _ |
5082 * @alias object |
5780 * @alias object |
5083 * @category Arrays |
5781 * @category Array |
5084 * @param {Array} keys The array of keys. |
5782 * @param {Array} props The property names. |
5085 * @param {Array} [values=[]] The array of values. |
5783 * @param {Array} [values=[]] The property values. |
5086 * @returns {Object} Returns an object composed of the given keys and |
5784 * @returns {Object} Returns the new object. |
5087 * corresponding values. |
5785 * @example |
5088 * @example |
5786 * |
|
5787 * _.zipObject([['fred', 30], ['barney', 40]]); |
|
5788 * // => { 'fred': 30, 'barney': 40 } |
5089 * |
5789 * |
5090 * _.zipObject(['fred', 'barney'], [30, 40]); |
5790 * _.zipObject(['fred', 'barney'], [30, 40]); |
5091 * // => { 'fred': 30, 'barney': 40 } |
5791 * // => { 'fred': 30, 'barney': 40 } |
5092 */ |
5792 */ |
5093 function zipObject(keys, values) { |
5793 function zipObject(props, values) { |
5094 var index = -1, |
5794 var index = -1, |
5095 length = keys ? keys.length : 0, |
5795 length = props ? props.length : 0, |
5096 result = {}; |
5796 result = {}; |
5097 |
5797 |
5098 if (!values && length && !isArray(keys[0])) { |
5798 if (length && !values && !isArray(props[0])) { |
5099 values = []; |
5799 values = []; |
5100 } |
5800 } |
5101 while (++index < length) { |
5801 while (++index < length) { |
5102 var key = keys[index]; |
5802 var key = props[index]; |
5103 if (values) { |
5803 if (values) { |
5104 result[key] = values[index]; |
5804 result[key] = values[index]; |
5105 } else if (key) { |
5805 } else if (key) { |
5106 result[key[0]] = key[1]; |
5806 result[key[0]] = key[1]; |
5107 } |
5807 } |
5108 } |
5808 } |
5109 return result; |
5809 return result; |
5110 } |
5810 } |
5111 |
5811 |
5112 /*--------------------------------------------------------------------------*/ |
5812 /** |
5113 |
5813 * This method is like `_.zip` except that it accepts an iteratee to specify |
5114 /** |
5814 * how grouped values should be combined. The `iteratee` is bound to `thisArg` |
5115 * Creates a function that executes `func`, with the `this` binding and |
5815 * and invoked with four arguments: (accumulator, value, index, group). |
5116 * arguments of the created function, only after being called `n` times. |
5816 * |
5117 * |
5817 * @static |
5118 * @static |
5818 * @memberOf _ |
5119 * @memberOf _ |
5819 * @category Array |
5120 * @category Functions |
5820 * @param {...Array} [arrays] The arrays to process. |
5121 * @param {number} n The number of times the function must be called before |
5821 * @param {Function} [iteratee] The function to combine grouped values. |
5122 * `func` is executed. |
5822 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
5823 * @returns {Array} Returns the new array of grouped elements. |
|
5824 * @example |
|
5825 * |
|
5826 * _.zipWith([1, 2], [10, 20], [100, 200], _.add); |
|
5827 * // => [111, 222] |
|
5828 */ |
|
5829 var zipWith = restParam(function(arrays) { |
|
5830 var length = arrays.length, |
|
5831 iteratee = length > 2 ? arrays[length - 2] : undefined, |
|
5832 thisArg = length > 1 ? arrays[length - 1] : undefined; |
|
5833 |
|
5834 if (length > 2 && typeof iteratee == 'function') { |
|
5835 length -= 2; |
|
5836 } else { |
|
5837 iteratee = (length > 1 && typeof thisArg == 'function') ? (--length, thisArg) : undefined; |
|
5838 thisArg = undefined; |
|
5839 } |
|
5840 arrays.length = length; |
|
5841 return unzipWith(arrays, iteratee, thisArg); |
|
5842 }); |
|
5843 |
|
5844 /*------------------------------------------------------------------------*/ |
|
5845 |
|
5846 /** |
|
5847 * Creates a `lodash` object that wraps `value` with explicit method |
|
5848 * chaining enabled. |
|
5849 * |
|
5850 * @static |
|
5851 * @memberOf _ |
|
5852 * @category Chain |
|
5853 * @param {*} value The value to wrap. |
|
5854 * @returns {Object} Returns the new `lodash` wrapper instance. |
|
5855 * @example |
|
5856 * |
|
5857 * var users = [ |
|
5858 * { 'user': 'barney', 'age': 36 }, |
|
5859 * { 'user': 'fred', 'age': 40 }, |
|
5860 * { 'user': 'pebbles', 'age': 1 } |
|
5861 * ]; |
|
5862 * |
|
5863 * var youngest = _.chain(users) |
|
5864 * .sortBy('age') |
|
5865 * .map(function(chr) { |
|
5866 * return chr.user + ' is ' + chr.age; |
|
5867 * }) |
|
5868 * .first() |
|
5869 * .value(); |
|
5870 * // => 'pebbles is 1' |
|
5871 */ |
|
5872 function chain(value) { |
|
5873 var result = lodash(value); |
|
5874 result.__chain__ = true; |
|
5875 return result; |
|
5876 } |
|
5877 |
|
5878 /** |
|
5879 * This method invokes `interceptor` and returns `value`. The interceptor is |
|
5880 * bound to `thisArg` and invoked with one argument; (value). The purpose of |
|
5881 * this method is to "tap into" a method chain in order to perform operations |
|
5882 * on intermediate results within the chain. |
|
5883 * |
|
5884 * @static |
|
5885 * @memberOf _ |
|
5886 * @category Chain |
|
5887 * @param {*} value The value to provide to `interceptor`. |
|
5888 * @param {Function} interceptor The function to invoke. |
|
5889 * @param {*} [thisArg] The `this` binding of `interceptor`. |
|
5890 * @returns {*} Returns `value`. |
|
5891 * @example |
|
5892 * |
|
5893 * _([1, 2, 3]) |
|
5894 * .tap(function(array) { |
|
5895 * array.pop(); |
|
5896 * }) |
|
5897 * .reverse() |
|
5898 * .value(); |
|
5899 * // => [2, 1] |
|
5900 */ |
|
5901 function tap(value, interceptor, thisArg) { |
|
5902 interceptor.call(thisArg, value); |
|
5903 return value; |
|
5904 } |
|
5905 |
|
5906 /** |
|
5907 * This method is like `_.tap` except that it returns the result of `interceptor`. |
|
5908 * |
|
5909 * @static |
|
5910 * @memberOf _ |
|
5911 * @category Chain |
|
5912 * @param {*} value The value to provide to `interceptor`. |
|
5913 * @param {Function} interceptor The function to invoke. |
|
5914 * @param {*} [thisArg] The `this` binding of `interceptor`. |
|
5915 * @returns {*} Returns the result of `interceptor`. |
|
5916 * @example |
|
5917 * |
|
5918 * _(' abc ') |
|
5919 * .chain() |
|
5920 * .trim() |
|
5921 * .thru(function(value) { |
|
5922 * return [value]; |
|
5923 * }) |
|
5924 * .value(); |
|
5925 * // => ['abc'] |
|
5926 */ |
|
5927 function thru(value, interceptor, thisArg) { |
|
5928 return interceptor.call(thisArg, value); |
|
5929 } |
|
5930 |
|
5931 /** |
|
5932 * Enables explicit method chaining on the wrapper object. |
|
5933 * |
|
5934 * @name chain |
|
5935 * @memberOf _ |
|
5936 * @category Chain |
|
5937 * @returns {Object} Returns the new `lodash` wrapper instance. |
|
5938 * @example |
|
5939 * |
|
5940 * var users = [ |
|
5941 * { 'user': 'barney', 'age': 36 }, |
|
5942 * { 'user': 'fred', 'age': 40 } |
|
5943 * ]; |
|
5944 * |
|
5945 * // without explicit chaining |
|
5946 * _(users).first(); |
|
5947 * // => { 'user': 'barney', 'age': 36 } |
|
5948 * |
|
5949 * // with explicit chaining |
|
5950 * _(users).chain() |
|
5951 * .first() |
|
5952 * .pick('user') |
|
5953 * .value(); |
|
5954 * // => { 'user': 'barney' } |
|
5955 */ |
|
5956 function wrapperChain() { |
|
5957 return chain(this); |
|
5958 } |
|
5959 |
|
5960 /** |
|
5961 * Executes the chained sequence and returns the wrapped result. |
|
5962 * |
|
5963 * @name commit |
|
5964 * @memberOf _ |
|
5965 * @category Chain |
|
5966 * @returns {Object} Returns the new `lodash` wrapper instance. |
|
5967 * @example |
|
5968 * |
|
5969 * var array = [1, 2]; |
|
5970 * var wrapped = _(array).push(3); |
|
5971 * |
|
5972 * console.log(array); |
|
5973 * // => [1, 2] |
|
5974 * |
|
5975 * wrapped = wrapped.commit(); |
|
5976 * console.log(array); |
|
5977 * // => [1, 2, 3] |
|
5978 * |
|
5979 * wrapped.last(); |
|
5980 * // => 3 |
|
5981 * |
|
5982 * console.log(array); |
|
5983 * // => [1, 2, 3] |
|
5984 */ |
|
5985 function wrapperCommit() { |
|
5986 return new LodashWrapper(this.value(), this.__chain__); |
|
5987 } |
|
5988 |
|
5989 /** |
|
5990 * Creates a new array joining a wrapped array with any additional arrays |
|
5991 * and/or values. |
|
5992 * |
|
5993 * @name concat |
|
5994 * @memberOf _ |
|
5995 * @category Chain |
|
5996 * @param {...*} [values] The values to concatenate. |
|
5997 * @returns {Array} Returns the new concatenated array. |
|
5998 * @example |
|
5999 * |
|
6000 * var array = [1]; |
|
6001 * var wrapped = _(array).concat(2, [3], [[4]]); |
|
6002 * |
|
6003 * console.log(wrapped.value()); |
|
6004 * // => [1, 2, 3, [4]] |
|
6005 * |
|
6006 * console.log(array); |
|
6007 * // => [1] |
|
6008 */ |
|
6009 var wrapperConcat = restParam(function(values) { |
|
6010 values = baseFlatten(values); |
|
6011 return this.thru(function(array) { |
|
6012 return arrayConcat(isArray(array) ? array : [toObject(array)], values); |
|
6013 }); |
|
6014 }); |
|
6015 |
|
6016 /** |
|
6017 * Creates a clone of the chained sequence planting `value` as the wrapped value. |
|
6018 * |
|
6019 * @name plant |
|
6020 * @memberOf _ |
|
6021 * @category Chain |
|
6022 * @returns {Object} Returns the new `lodash` wrapper instance. |
|
6023 * @example |
|
6024 * |
|
6025 * var array = [1, 2]; |
|
6026 * var wrapped = _(array).map(function(value) { |
|
6027 * return Math.pow(value, 2); |
|
6028 * }); |
|
6029 * |
|
6030 * var other = [3, 4]; |
|
6031 * var otherWrapped = wrapped.plant(other); |
|
6032 * |
|
6033 * otherWrapped.value(); |
|
6034 * // => [9, 16] |
|
6035 * |
|
6036 * wrapped.value(); |
|
6037 * // => [1, 4] |
|
6038 */ |
|
6039 function wrapperPlant(value) { |
|
6040 var result, |
|
6041 parent = this; |
|
6042 |
|
6043 while (parent instanceof baseLodash) { |
|
6044 var clone = wrapperClone(parent); |
|
6045 if (result) { |
|
6046 previous.__wrapped__ = clone; |
|
6047 } else { |
|
6048 result = clone; |
|
6049 } |
|
6050 var previous = clone; |
|
6051 parent = parent.__wrapped__; |
|
6052 } |
|
6053 previous.__wrapped__ = value; |
|
6054 return result; |
|
6055 } |
|
6056 |
|
6057 /** |
|
6058 * Reverses the wrapped array so the first element becomes the last, the |
|
6059 * second element becomes the second to last, and so on. |
|
6060 * |
|
6061 * **Note:** This method mutates the wrapped array. |
|
6062 * |
|
6063 * @name reverse |
|
6064 * @memberOf _ |
|
6065 * @category Chain |
|
6066 * @returns {Object} Returns the new reversed `lodash` wrapper instance. |
|
6067 * @example |
|
6068 * |
|
6069 * var array = [1, 2, 3]; |
|
6070 * |
|
6071 * _(array).reverse().value() |
|
6072 * // => [3, 2, 1] |
|
6073 * |
|
6074 * console.log(array); |
|
6075 * // => [3, 2, 1] |
|
6076 */ |
|
6077 function wrapperReverse() { |
|
6078 var value = this.__wrapped__; |
|
6079 |
|
6080 var interceptor = function(value) { |
|
6081 return value.reverse(); |
|
6082 }; |
|
6083 if (value instanceof LazyWrapper) { |
|
6084 var wrapped = value; |
|
6085 if (this.__actions__.length) { |
|
6086 wrapped = new LazyWrapper(this); |
|
6087 } |
|
6088 wrapped = wrapped.reverse(); |
|
6089 wrapped.__actions__.push({ 'func': thru, 'args': [interceptor], 'thisArg': undefined }); |
|
6090 return new LodashWrapper(wrapped, this.__chain__); |
|
6091 } |
|
6092 return this.thru(interceptor); |
|
6093 } |
|
6094 |
|
6095 /** |
|
6096 * Produces the result of coercing the unwrapped value to a string. |
|
6097 * |
|
6098 * @name toString |
|
6099 * @memberOf _ |
|
6100 * @category Chain |
|
6101 * @returns {string} Returns the coerced string value. |
|
6102 * @example |
|
6103 * |
|
6104 * _([1, 2, 3]).toString(); |
|
6105 * // => '1,2,3' |
|
6106 */ |
|
6107 function wrapperToString() { |
|
6108 return (this.value() + ''); |
|
6109 } |
|
6110 |
|
6111 /** |
|
6112 * Executes the chained sequence to extract the unwrapped value. |
|
6113 * |
|
6114 * @name value |
|
6115 * @memberOf _ |
|
6116 * @alias run, toJSON, valueOf |
|
6117 * @category Chain |
|
6118 * @returns {*} Returns the resolved unwrapped value. |
|
6119 * @example |
|
6120 * |
|
6121 * _([1, 2, 3]).value(); |
|
6122 * // => [1, 2, 3] |
|
6123 */ |
|
6124 function wrapperValue() { |
|
6125 return baseWrapperValue(this.__wrapped__, this.__actions__); |
|
6126 } |
|
6127 |
|
6128 /*------------------------------------------------------------------------*/ |
|
6129 |
|
6130 /** |
|
6131 * Creates an array of elements corresponding to the given keys, or indexes, |
|
6132 * of `collection`. Keys may be specified as individual arguments or as arrays |
|
6133 * of keys. |
|
6134 * |
|
6135 * @static |
|
6136 * @memberOf _ |
|
6137 * @category Collection |
|
6138 * @param {Array|Object|string} collection The collection to iterate over. |
|
6139 * @param {...(number|number[]|string|string[])} [props] The property names |
|
6140 * or indexes of elements to pick, specified individually or in arrays. |
|
6141 * @returns {Array} Returns the new array of picked elements. |
|
6142 * @example |
|
6143 * |
|
6144 * _.at(['a', 'b', 'c'], [0, 2]); |
|
6145 * // => ['a', 'c'] |
|
6146 * |
|
6147 * _.at(['barney', 'fred', 'pebbles'], 0, 2); |
|
6148 * // => ['barney', 'pebbles'] |
|
6149 */ |
|
6150 var at = restParam(function(collection, props) { |
|
6151 return baseAt(collection, baseFlatten(props)); |
|
6152 }); |
|
6153 |
|
6154 /** |
|
6155 * Creates an object composed of keys generated from the results of running |
|
6156 * each element of `collection` through `iteratee`. The corresponding value |
|
6157 * of each key is the number of times the key was returned by `iteratee`. |
|
6158 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
|
6159 * (value, index|key, collection). |
|
6160 * |
|
6161 * If a property name is provided for `iteratee` the created `_.property` |
|
6162 * style callback returns the property value of the given element. |
|
6163 * |
|
6164 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6165 * style callback returns `true` for elements that have a matching property |
|
6166 * value, else `false`. |
|
6167 * |
|
6168 * If an object is provided for `iteratee` the created `_.matches` style |
|
6169 * callback returns `true` for elements that have the properties of the given |
|
6170 * object, else `false`. |
|
6171 * |
|
6172 * @static |
|
6173 * @memberOf _ |
|
6174 * @category Collection |
|
6175 * @param {Array|Object|string} collection The collection to iterate over. |
|
6176 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
6177 * per iteration. |
|
6178 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6179 * @returns {Object} Returns the composed aggregate object. |
|
6180 * @example |
|
6181 * |
|
6182 * _.countBy([4.3, 6.1, 6.4], function(n) { |
|
6183 * return Math.floor(n); |
|
6184 * }); |
|
6185 * // => { '4': 1, '6': 2 } |
|
6186 * |
|
6187 * _.countBy([4.3, 6.1, 6.4], function(n) { |
|
6188 * return this.floor(n); |
|
6189 * }, Math); |
|
6190 * // => { '4': 1, '6': 2 } |
|
6191 * |
|
6192 * _.countBy(['one', 'two', 'three'], 'length'); |
|
6193 * // => { '3': 2, '5': 1 } |
|
6194 */ |
|
6195 var countBy = createAggregator(function(result, value, key) { |
|
6196 hasOwnProperty.call(result, key) ? ++result[key] : (result[key] = 1); |
|
6197 }); |
|
6198 |
|
6199 /** |
|
6200 * Checks if `predicate` returns truthy for **all** elements of `collection`. |
|
6201 * The predicate is bound to `thisArg` and invoked with three arguments: |
|
6202 * (value, index|key, collection). |
|
6203 * |
|
6204 * If a property name is provided for `predicate` the created `_.property` |
|
6205 * style callback returns the property value of the given element. |
|
6206 * |
|
6207 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6208 * style callback returns `true` for elements that have a matching property |
|
6209 * value, else `false`. |
|
6210 * |
|
6211 * If an object is provided for `predicate` the created `_.matches` style |
|
6212 * callback returns `true` for elements that have the properties of the given |
|
6213 * object, else `false`. |
|
6214 * |
|
6215 * @static |
|
6216 * @memberOf _ |
|
6217 * @alias all |
|
6218 * @category Collection |
|
6219 * @param {Array|Object|string} collection The collection to iterate over. |
|
6220 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6221 * per iteration. |
|
6222 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6223 * @returns {boolean} Returns `true` if all elements pass the predicate check, |
|
6224 * else `false`. |
|
6225 * @example |
|
6226 * |
|
6227 * _.every([true, 1, null, 'yes'], Boolean); |
|
6228 * // => false |
|
6229 * |
|
6230 * var users = [ |
|
6231 * { 'user': 'barney', 'active': false }, |
|
6232 * { 'user': 'fred', 'active': false } |
|
6233 * ]; |
|
6234 * |
|
6235 * // using the `_.matches` callback shorthand |
|
6236 * _.every(users, { 'user': 'barney', 'active': false }); |
|
6237 * // => false |
|
6238 * |
|
6239 * // using the `_.matchesProperty` callback shorthand |
|
6240 * _.every(users, 'active', false); |
|
6241 * // => true |
|
6242 * |
|
6243 * // using the `_.property` callback shorthand |
|
6244 * _.every(users, 'active'); |
|
6245 * // => false |
|
6246 */ |
|
6247 function every(collection, predicate, thisArg) { |
|
6248 var func = isArray(collection) ? arrayEvery : baseEvery; |
|
6249 if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
|
6250 predicate = undefined; |
|
6251 } |
|
6252 if (typeof predicate != 'function' || thisArg !== undefined) { |
|
6253 predicate = getCallback(predicate, thisArg, 3); |
|
6254 } |
|
6255 return func(collection, predicate); |
|
6256 } |
|
6257 |
|
6258 /** |
|
6259 * Iterates over elements of `collection`, returning an array of all elements |
|
6260 * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
|
6261 * invoked with three arguments: (value, index|key, collection). |
|
6262 * |
|
6263 * If a property name is provided for `predicate` the created `_.property` |
|
6264 * style callback returns the property value of the given element. |
|
6265 * |
|
6266 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6267 * style callback returns `true` for elements that have a matching property |
|
6268 * value, else `false`. |
|
6269 * |
|
6270 * If an object is provided for `predicate` the created `_.matches` style |
|
6271 * callback returns `true` for elements that have the properties of the given |
|
6272 * object, else `false`. |
|
6273 * |
|
6274 * @static |
|
6275 * @memberOf _ |
|
6276 * @alias select |
|
6277 * @category Collection |
|
6278 * @param {Array|Object|string} collection The collection to iterate over. |
|
6279 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6280 * per iteration. |
|
6281 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6282 * @returns {Array} Returns the new filtered array. |
|
6283 * @example |
|
6284 * |
|
6285 * _.filter([4, 5, 6], function(n) { |
|
6286 * return n % 2 == 0; |
|
6287 * }); |
|
6288 * // => [4, 6] |
|
6289 * |
|
6290 * var users = [ |
|
6291 * { 'user': 'barney', 'age': 36, 'active': true }, |
|
6292 * { 'user': 'fred', 'age': 40, 'active': false } |
|
6293 * ]; |
|
6294 * |
|
6295 * // using the `_.matches` callback shorthand |
|
6296 * _.pluck(_.filter(users, { 'age': 36, 'active': true }), 'user'); |
|
6297 * // => ['barney'] |
|
6298 * |
|
6299 * // using the `_.matchesProperty` callback shorthand |
|
6300 * _.pluck(_.filter(users, 'active', false), 'user'); |
|
6301 * // => ['fred'] |
|
6302 * |
|
6303 * // using the `_.property` callback shorthand |
|
6304 * _.pluck(_.filter(users, 'active'), 'user'); |
|
6305 * // => ['barney'] |
|
6306 */ |
|
6307 function filter(collection, predicate, thisArg) { |
|
6308 var func = isArray(collection) ? arrayFilter : baseFilter; |
|
6309 predicate = getCallback(predicate, thisArg, 3); |
|
6310 return func(collection, predicate); |
|
6311 } |
|
6312 |
|
6313 /** |
|
6314 * Iterates over elements of `collection`, returning the first element |
|
6315 * `predicate` returns truthy for. The predicate is bound to `thisArg` and |
|
6316 * invoked with three arguments: (value, index|key, collection). |
|
6317 * |
|
6318 * If a property name is provided for `predicate` the created `_.property` |
|
6319 * style callback returns the property value of the given element. |
|
6320 * |
|
6321 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6322 * style callback returns `true` for elements that have a matching property |
|
6323 * value, else `false`. |
|
6324 * |
|
6325 * If an object is provided for `predicate` the created `_.matches` style |
|
6326 * callback returns `true` for elements that have the properties of the given |
|
6327 * object, else `false`. |
|
6328 * |
|
6329 * @static |
|
6330 * @memberOf _ |
|
6331 * @alias detect |
|
6332 * @category Collection |
|
6333 * @param {Array|Object|string} collection The collection to search. |
|
6334 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6335 * per iteration. |
|
6336 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6337 * @returns {*} Returns the matched element, else `undefined`. |
|
6338 * @example |
|
6339 * |
|
6340 * var users = [ |
|
6341 * { 'user': 'barney', 'age': 36, 'active': true }, |
|
6342 * { 'user': 'fred', 'age': 40, 'active': false }, |
|
6343 * { 'user': 'pebbles', 'age': 1, 'active': true } |
|
6344 * ]; |
|
6345 * |
|
6346 * _.result(_.find(users, function(chr) { |
|
6347 * return chr.age < 40; |
|
6348 * }), 'user'); |
|
6349 * // => 'barney' |
|
6350 * |
|
6351 * // using the `_.matches` callback shorthand |
|
6352 * _.result(_.find(users, { 'age': 1, 'active': true }), 'user'); |
|
6353 * // => 'pebbles' |
|
6354 * |
|
6355 * // using the `_.matchesProperty` callback shorthand |
|
6356 * _.result(_.find(users, 'active', false), 'user'); |
|
6357 * // => 'fred' |
|
6358 * |
|
6359 * // using the `_.property` callback shorthand |
|
6360 * _.result(_.find(users, 'active'), 'user'); |
|
6361 * // => 'barney' |
|
6362 */ |
|
6363 var find = createFind(baseEach); |
|
6364 |
|
6365 /** |
|
6366 * This method is like `_.find` except that it iterates over elements of |
|
6367 * `collection` from right to left. |
|
6368 * |
|
6369 * @static |
|
6370 * @memberOf _ |
|
6371 * @category Collection |
|
6372 * @param {Array|Object|string} collection The collection to search. |
|
6373 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6374 * per iteration. |
|
6375 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6376 * @returns {*} Returns the matched element, else `undefined`. |
|
6377 * @example |
|
6378 * |
|
6379 * _.findLast([1, 2, 3, 4], function(n) { |
|
6380 * return n % 2 == 1; |
|
6381 * }); |
|
6382 * // => 3 |
|
6383 */ |
|
6384 var findLast = createFind(baseEachRight, true); |
|
6385 |
|
6386 /** |
|
6387 * Performs a deep comparison between each element in `collection` and the |
|
6388 * source object, returning the first element that has equivalent property |
|
6389 * values. |
|
6390 * |
|
6391 * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
|
6392 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
|
6393 * their own, not inherited, enumerable properties. For comparing a single |
|
6394 * own or inherited property value see `_.matchesProperty`. |
|
6395 * |
|
6396 * @static |
|
6397 * @memberOf _ |
|
6398 * @category Collection |
|
6399 * @param {Array|Object|string} collection The collection to search. |
|
6400 * @param {Object} source The object of property values to match. |
|
6401 * @returns {*} Returns the matched element, else `undefined`. |
|
6402 * @example |
|
6403 * |
|
6404 * var users = [ |
|
6405 * { 'user': 'barney', 'age': 36, 'active': true }, |
|
6406 * { 'user': 'fred', 'age': 40, 'active': false } |
|
6407 * ]; |
|
6408 * |
|
6409 * _.result(_.findWhere(users, { 'age': 36, 'active': true }), 'user'); |
|
6410 * // => 'barney' |
|
6411 * |
|
6412 * _.result(_.findWhere(users, { 'age': 40, 'active': false }), 'user'); |
|
6413 * // => 'fred' |
|
6414 */ |
|
6415 function findWhere(collection, source) { |
|
6416 return find(collection, baseMatches(source)); |
|
6417 } |
|
6418 |
|
6419 /** |
|
6420 * Iterates over elements of `collection` invoking `iteratee` for each element. |
|
6421 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
|
6422 * (value, index|key, collection). Iteratee functions may exit iteration early |
|
6423 * by explicitly returning `false`. |
|
6424 * |
|
6425 * **Note:** As with other "Collections" methods, objects with a "length" property |
|
6426 * are iterated like arrays. To avoid this behavior `_.forIn` or `_.forOwn` |
|
6427 * may be used for object iteration. |
|
6428 * |
|
6429 * @static |
|
6430 * @memberOf _ |
|
6431 * @alias each |
|
6432 * @category Collection |
|
6433 * @param {Array|Object|string} collection The collection to iterate over. |
|
6434 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
6435 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6436 * @returns {Array|Object|string} Returns `collection`. |
|
6437 * @example |
|
6438 * |
|
6439 * _([1, 2]).forEach(function(n) { |
|
6440 * console.log(n); |
|
6441 * }).value(); |
|
6442 * // => logs each value from left to right and returns the array |
|
6443 * |
|
6444 * _.forEach({ 'a': 1, 'b': 2 }, function(n, key) { |
|
6445 * console.log(n, key); |
|
6446 * }); |
|
6447 * // => logs each value-key pair and returns the object (iteration order is not guaranteed) |
|
6448 */ |
|
6449 var forEach = createForEach(arrayEach, baseEach); |
|
6450 |
|
6451 /** |
|
6452 * This method is like `_.forEach` except that it iterates over elements of |
|
6453 * `collection` from right to left. |
|
6454 * |
|
6455 * @static |
|
6456 * @memberOf _ |
|
6457 * @alias eachRight |
|
6458 * @category Collection |
|
6459 * @param {Array|Object|string} collection The collection to iterate over. |
|
6460 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
6461 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6462 * @returns {Array|Object|string} Returns `collection`. |
|
6463 * @example |
|
6464 * |
|
6465 * _([1, 2]).forEachRight(function(n) { |
|
6466 * console.log(n); |
|
6467 * }).value(); |
|
6468 * // => logs each value from right to left and returns the array |
|
6469 */ |
|
6470 var forEachRight = createForEach(arrayEachRight, baseEachRight); |
|
6471 |
|
6472 /** |
|
6473 * Creates an object composed of keys generated from the results of running |
|
6474 * each element of `collection` through `iteratee`. The corresponding value |
|
6475 * of each key is an array of the elements responsible for generating the key. |
|
6476 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
|
6477 * (value, index|key, collection). |
|
6478 * |
|
6479 * If a property name is provided for `iteratee` the created `_.property` |
|
6480 * style callback returns the property value of the given element. |
|
6481 * |
|
6482 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6483 * style callback returns `true` for elements that have a matching property |
|
6484 * value, else `false`. |
|
6485 * |
|
6486 * If an object is provided for `iteratee` the created `_.matches` style |
|
6487 * callback returns `true` for elements that have the properties of the given |
|
6488 * object, else `false`. |
|
6489 * |
|
6490 * @static |
|
6491 * @memberOf _ |
|
6492 * @category Collection |
|
6493 * @param {Array|Object|string} collection The collection to iterate over. |
|
6494 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
6495 * per iteration. |
|
6496 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6497 * @returns {Object} Returns the composed aggregate object. |
|
6498 * @example |
|
6499 * |
|
6500 * _.groupBy([4.2, 6.1, 6.4], function(n) { |
|
6501 * return Math.floor(n); |
|
6502 * }); |
|
6503 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
6504 * |
|
6505 * _.groupBy([4.2, 6.1, 6.4], function(n) { |
|
6506 * return this.floor(n); |
|
6507 * }, Math); |
|
6508 * // => { '4': [4.2], '6': [6.1, 6.4] } |
|
6509 * |
|
6510 * // using the `_.property` callback shorthand |
|
6511 * _.groupBy(['one', 'two', 'three'], 'length'); |
|
6512 * // => { '3': ['one', 'two'], '5': ['three'] } |
|
6513 */ |
|
6514 var groupBy = createAggregator(function(result, value, key) { |
|
6515 if (hasOwnProperty.call(result, key)) { |
|
6516 result[key].push(value); |
|
6517 } else { |
|
6518 result[key] = [value]; |
|
6519 } |
|
6520 }); |
|
6521 |
|
6522 /** |
|
6523 * Checks if `target` is in `collection` using |
|
6524 * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) |
|
6525 * for equality comparisons. If `fromIndex` is negative, it's used as the offset |
|
6526 * from the end of `collection`. |
|
6527 * |
|
6528 * @static |
|
6529 * @memberOf _ |
|
6530 * @alias contains, include |
|
6531 * @category Collection |
|
6532 * @param {Array|Object|string} collection The collection to search. |
|
6533 * @param {*} target The value to search for. |
|
6534 * @param {number} [fromIndex=0] The index to search from. |
|
6535 * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
|
6536 * @returns {boolean} Returns `true` if a matching element is found, else `false`. |
|
6537 * @example |
|
6538 * |
|
6539 * _.includes([1, 2, 3], 1); |
|
6540 * // => true |
|
6541 * |
|
6542 * _.includes([1, 2, 3], 1, 2); |
|
6543 * // => false |
|
6544 * |
|
6545 * _.includes({ 'user': 'fred', 'age': 40 }, 'fred'); |
|
6546 * // => true |
|
6547 * |
|
6548 * _.includes('pebbles', 'eb'); |
|
6549 * // => true |
|
6550 */ |
|
6551 function includes(collection, target, fromIndex, guard) { |
|
6552 var length = collection ? getLength(collection) : 0; |
|
6553 if (!isLength(length)) { |
|
6554 collection = values(collection); |
|
6555 length = collection.length; |
|
6556 } |
|
6557 if (typeof fromIndex != 'number' || (guard && isIterateeCall(target, fromIndex, guard))) { |
|
6558 fromIndex = 0; |
|
6559 } else { |
|
6560 fromIndex = fromIndex < 0 ? nativeMax(length + fromIndex, 0) : (fromIndex || 0); |
|
6561 } |
|
6562 return (typeof collection == 'string' || !isArray(collection) && isString(collection)) |
|
6563 ? (fromIndex <= length && collection.indexOf(target, fromIndex) > -1) |
|
6564 : (!!length && getIndexOf(collection, target, fromIndex) > -1); |
|
6565 } |
|
6566 |
|
6567 /** |
|
6568 * Creates an object composed of keys generated from the results of running |
|
6569 * each element of `collection` through `iteratee`. The corresponding value |
|
6570 * of each key is the last element responsible for generating the key. The |
|
6571 * iteratee function is bound to `thisArg` and invoked with three arguments: |
|
6572 * (value, index|key, collection). |
|
6573 * |
|
6574 * If a property name is provided for `iteratee` the created `_.property` |
|
6575 * style callback returns the property value of the given element. |
|
6576 * |
|
6577 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6578 * style callback returns `true` for elements that have a matching property |
|
6579 * value, else `false`. |
|
6580 * |
|
6581 * If an object is provided for `iteratee` the created `_.matches` style |
|
6582 * callback returns `true` for elements that have the properties of the given |
|
6583 * object, else `false`. |
|
6584 * |
|
6585 * @static |
|
6586 * @memberOf _ |
|
6587 * @category Collection |
|
6588 * @param {Array|Object|string} collection The collection to iterate over. |
|
6589 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
6590 * per iteration. |
|
6591 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6592 * @returns {Object} Returns the composed aggregate object. |
|
6593 * @example |
|
6594 * |
|
6595 * var keyData = [ |
|
6596 * { 'dir': 'left', 'code': 97 }, |
|
6597 * { 'dir': 'right', 'code': 100 } |
|
6598 * ]; |
|
6599 * |
|
6600 * _.indexBy(keyData, 'dir'); |
|
6601 * // => { 'left': { 'dir': 'left', 'code': 97 }, 'right': { 'dir': 'right', 'code': 100 } } |
|
6602 * |
|
6603 * _.indexBy(keyData, function(object) { |
|
6604 * return String.fromCharCode(object.code); |
|
6605 * }); |
|
6606 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
6607 * |
|
6608 * _.indexBy(keyData, function(object) { |
|
6609 * return this.fromCharCode(object.code); |
|
6610 * }, String); |
|
6611 * // => { 'a': { 'dir': 'left', 'code': 97 }, 'd': { 'dir': 'right', 'code': 100 } } |
|
6612 */ |
|
6613 var indexBy = createAggregator(function(result, value, key) { |
|
6614 result[key] = value; |
|
6615 }); |
|
6616 |
|
6617 /** |
|
6618 * Invokes the method at `path` of each element in `collection`, returning |
|
6619 * an array of the results of each invoked method. Any additional arguments |
|
6620 * are provided to each invoked method. If `methodName` is a function it's |
|
6621 * invoked for, and `this` bound to, each element in `collection`. |
|
6622 * |
|
6623 * @static |
|
6624 * @memberOf _ |
|
6625 * @category Collection |
|
6626 * @param {Array|Object|string} collection The collection to iterate over. |
|
6627 * @param {Array|Function|string} path The path of the method to invoke or |
|
6628 * the function invoked per iteration. |
|
6629 * @param {...*} [args] The arguments to invoke the method with. |
|
6630 * @returns {Array} Returns the array of results. |
|
6631 * @example |
|
6632 * |
|
6633 * _.invoke([[5, 1, 7], [3, 2, 1]], 'sort'); |
|
6634 * // => [[1, 5, 7], [1, 2, 3]] |
|
6635 * |
|
6636 * _.invoke([123, 456], String.prototype.split, ''); |
|
6637 * // => [['1', '2', '3'], ['4', '5', '6']] |
|
6638 */ |
|
6639 var invoke = restParam(function(collection, path, args) { |
|
6640 var index = -1, |
|
6641 isFunc = typeof path == 'function', |
|
6642 isProp = isKey(path), |
|
6643 result = isArrayLike(collection) ? Array(collection.length) : []; |
|
6644 |
|
6645 baseEach(collection, function(value) { |
|
6646 var func = isFunc ? path : ((isProp && value != null) ? value[path] : undefined); |
|
6647 result[++index] = func ? func.apply(value, args) : invokePath(value, path, args); |
|
6648 }); |
|
6649 return result; |
|
6650 }); |
|
6651 |
|
6652 /** |
|
6653 * Creates an array of values by running each element in `collection` through |
|
6654 * `iteratee`. The `iteratee` is bound to `thisArg` and invoked with three |
|
6655 * arguments: (value, index|key, collection). |
|
6656 * |
|
6657 * If a property name is provided for `iteratee` the created `_.property` |
|
6658 * style callback returns the property value of the given element. |
|
6659 * |
|
6660 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6661 * style callback returns `true` for elements that have a matching property |
|
6662 * value, else `false`. |
|
6663 * |
|
6664 * If an object is provided for `iteratee` the created `_.matches` style |
|
6665 * callback returns `true` for elements that have the properties of the given |
|
6666 * object, else `false`. |
|
6667 * |
|
6668 * Many lodash methods are guarded to work as iteratees for methods like |
|
6669 * `_.every`, `_.filter`, `_.map`, `_.mapValues`, `_.reject`, and `_.some`. |
|
6670 * |
|
6671 * The guarded methods are: |
|
6672 * `ary`, `callback`, `chunk`, `clone`, `create`, `curry`, `curryRight`, |
|
6673 * `drop`, `dropRight`, `every`, `fill`, `flatten`, `invert`, `max`, `min`, |
|
6674 * `parseInt`, `slice`, `sortBy`, `take`, `takeRight`, `template`, `trim`, |
|
6675 * `trimLeft`, `trimRight`, `trunc`, `random`, `range`, `sample`, `some`, |
|
6676 * `sum`, `uniq`, and `words` |
|
6677 * |
|
6678 * @static |
|
6679 * @memberOf _ |
|
6680 * @alias collect |
|
6681 * @category Collection |
|
6682 * @param {Array|Object|string} collection The collection to iterate over. |
|
6683 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
6684 * per iteration. |
|
6685 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6686 * @returns {Array} Returns the new mapped array. |
|
6687 * @example |
|
6688 * |
|
6689 * function timesThree(n) { |
|
6690 * return n * 3; |
|
6691 * } |
|
6692 * |
|
6693 * _.map([1, 2], timesThree); |
|
6694 * // => [3, 6] |
|
6695 * |
|
6696 * _.map({ 'a': 1, 'b': 2 }, timesThree); |
|
6697 * // => [3, 6] (iteration order is not guaranteed) |
|
6698 * |
|
6699 * var users = [ |
|
6700 * { 'user': 'barney' }, |
|
6701 * { 'user': 'fred' } |
|
6702 * ]; |
|
6703 * |
|
6704 * // using the `_.property` callback shorthand |
|
6705 * _.map(users, 'user'); |
|
6706 * // => ['barney', 'fred'] |
|
6707 */ |
|
6708 function map(collection, iteratee, thisArg) { |
|
6709 var func = isArray(collection) ? arrayMap : baseMap; |
|
6710 iteratee = getCallback(iteratee, thisArg, 3); |
|
6711 return func(collection, iteratee); |
|
6712 } |
|
6713 |
|
6714 /** |
|
6715 * Creates an array of elements split into two groups, the first of which |
|
6716 * contains elements `predicate` returns truthy for, while the second of which |
|
6717 * contains elements `predicate` returns falsey for. The predicate is bound |
|
6718 * to `thisArg` and invoked with three arguments: (value, index|key, collection). |
|
6719 * |
|
6720 * If a property name is provided for `predicate` the created `_.property` |
|
6721 * style callback returns the property value of the given element. |
|
6722 * |
|
6723 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
6724 * style callback returns `true` for elements that have a matching property |
|
6725 * value, else `false`. |
|
6726 * |
|
6727 * If an object is provided for `predicate` the created `_.matches` style |
|
6728 * callback returns `true` for elements that have the properties of the given |
|
6729 * object, else `false`. |
|
6730 * |
|
6731 * @static |
|
6732 * @memberOf _ |
|
6733 * @category Collection |
|
6734 * @param {Array|Object|string} collection The collection to iterate over. |
|
6735 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6736 * per iteration. |
|
6737 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6738 * @returns {Array} Returns the array of grouped elements. |
|
6739 * @example |
|
6740 * |
|
6741 * _.partition([1, 2, 3], function(n) { |
|
6742 * return n % 2; |
|
6743 * }); |
|
6744 * // => [[1, 3], [2]] |
|
6745 * |
|
6746 * _.partition([1.2, 2.3, 3.4], function(n) { |
|
6747 * return this.floor(n) % 2; |
|
6748 * }, Math); |
|
6749 * // => [[1.2, 3.4], [2.3]] |
|
6750 * |
|
6751 * var users = [ |
|
6752 * { 'user': 'barney', 'age': 36, 'active': false }, |
|
6753 * { 'user': 'fred', 'age': 40, 'active': true }, |
|
6754 * { 'user': 'pebbles', 'age': 1, 'active': false } |
|
6755 * ]; |
|
6756 * |
|
6757 * var mapper = function(array) { |
|
6758 * return _.pluck(array, 'user'); |
|
6759 * }; |
|
6760 * |
|
6761 * // using the `_.matches` callback shorthand |
|
6762 * _.map(_.partition(users, { 'age': 1, 'active': false }), mapper); |
|
6763 * // => [['pebbles'], ['barney', 'fred']] |
|
6764 * |
|
6765 * // using the `_.matchesProperty` callback shorthand |
|
6766 * _.map(_.partition(users, 'active', false), mapper); |
|
6767 * // => [['barney', 'pebbles'], ['fred']] |
|
6768 * |
|
6769 * // using the `_.property` callback shorthand |
|
6770 * _.map(_.partition(users, 'active'), mapper); |
|
6771 * // => [['fred'], ['barney', 'pebbles']] |
|
6772 */ |
|
6773 var partition = createAggregator(function(result, value, key) { |
|
6774 result[key ? 0 : 1].push(value); |
|
6775 }, function() { return [[], []]; }); |
|
6776 |
|
6777 /** |
|
6778 * Gets the property value of `path` from all elements in `collection`. |
|
6779 * |
|
6780 * @static |
|
6781 * @memberOf _ |
|
6782 * @category Collection |
|
6783 * @param {Array|Object|string} collection The collection to iterate over. |
|
6784 * @param {Array|string} path The path of the property to pluck. |
|
6785 * @returns {Array} Returns the property values. |
|
6786 * @example |
|
6787 * |
|
6788 * var users = [ |
|
6789 * { 'user': 'barney', 'age': 36 }, |
|
6790 * { 'user': 'fred', 'age': 40 } |
|
6791 * ]; |
|
6792 * |
|
6793 * _.pluck(users, 'user'); |
|
6794 * // => ['barney', 'fred'] |
|
6795 * |
|
6796 * var userIndex = _.indexBy(users, 'user'); |
|
6797 * _.pluck(userIndex, 'age'); |
|
6798 * // => [36, 40] (iteration order is not guaranteed) |
|
6799 */ |
|
6800 function pluck(collection, path) { |
|
6801 return map(collection, property(path)); |
|
6802 } |
|
6803 |
|
6804 /** |
|
6805 * Reduces `collection` to a value which is the accumulated result of running |
|
6806 * each element in `collection` through `iteratee`, where each successive |
|
6807 * invocation is supplied the return value of the previous. If `accumulator` |
|
6808 * is not provided the first element of `collection` is used as the initial |
|
6809 * value. The `iteratee` is bound to `thisArg` and invoked with four arguments: |
|
6810 * (accumulator, value, index|key, collection). |
|
6811 * |
|
6812 * Many lodash methods are guarded to work as iteratees for methods like |
|
6813 * `_.reduce`, `_.reduceRight`, and `_.transform`. |
|
6814 * |
|
6815 * The guarded methods are: |
|
6816 * `assign`, `defaults`, `defaultsDeep`, `includes`, `merge`, `sortByAll`, |
|
6817 * and `sortByOrder` |
|
6818 * |
|
6819 * @static |
|
6820 * @memberOf _ |
|
6821 * @alias foldl, inject |
|
6822 * @category Collection |
|
6823 * @param {Array|Object|string} collection The collection to iterate over. |
|
6824 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
6825 * @param {*} [accumulator] The initial value. |
|
6826 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6827 * @returns {*} Returns the accumulated value. |
|
6828 * @example |
|
6829 * |
|
6830 * _.reduce([1, 2], function(total, n) { |
|
6831 * return total + n; |
|
6832 * }); |
|
6833 * // => 3 |
|
6834 * |
|
6835 * _.reduce({ 'a': 1, 'b': 2 }, function(result, n, key) { |
|
6836 * result[key] = n * 3; |
|
6837 * return result; |
|
6838 * }, {}); |
|
6839 * // => { 'a': 3, 'b': 6 } (iteration order is not guaranteed) |
|
6840 */ |
|
6841 var reduce = createReduce(arrayReduce, baseEach); |
|
6842 |
|
6843 /** |
|
6844 * This method is like `_.reduce` except that it iterates over elements of |
|
6845 * `collection` from right to left. |
|
6846 * |
|
6847 * @static |
|
6848 * @memberOf _ |
|
6849 * @alias foldr |
|
6850 * @category Collection |
|
6851 * @param {Array|Object|string} collection The collection to iterate over. |
|
6852 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
6853 * @param {*} [accumulator] The initial value. |
|
6854 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
6855 * @returns {*} Returns the accumulated value. |
|
6856 * @example |
|
6857 * |
|
6858 * var array = [[0, 1], [2, 3], [4, 5]]; |
|
6859 * |
|
6860 * _.reduceRight(array, function(flattened, other) { |
|
6861 * return flattened.concat(other); |
|
6862 * }, []); |
|
6863 * // => [4, 5, 2, 3, 0, 1] |
|
6864 */ |
|
6865 var reduceRight = createReduce(arrayReduceRight, baseEachRight); |
|
6866 |
|
6867 /** |
|
6868 * The opposite of `_.filter`; this method returns the elements of `collection` |
|
6869 * that `predicate` does **not** return truthy for. |
|
6870 * |
|
6871 * @static |
|
6872 * @memberOf _ |
|
6873 * @category Collection |
|
6874 * @param {Array|Object|string} collection The collection to iterate over. |
|
6875 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
6876 * per iteration. |
|
6877 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
6878 * @returns {Array} Returns the new filtered array. |
|
6879 * @example |
|
6880 * |
|
6881 * _.reject([1, 2, 3, 4], function(n) { |
|
6882 * return n % 2 == 0; |
|
6883 * }); |
|
6884 * // => [1, 3] |
|
6885 * |
|
6886 * var users = [ |
|
6887 * { 'user': 'barney', 'age': 36, 'active': false }, |
|
6888 * { 'user': 'fred', 'age': 40, 'active': true } |
|
6889 * ]; |
|
6890 * |
|
6891 * // using the `_.matches` callback shorthand |
|
6892 * _.pluck(_.reject(users, { 'age': 40, 'active': true }), 'user'); |
|
6893 * // => ['barney'] |
|
6894 * |
|
6895 * // using the `_.matchesProperty` callback shorthand |
|
6896 * _.pluck(_.reject(users, 'active', false), 'user'); |
|
6897 * // => ['fred'] |
|
6898 * |
|
6899 * // using the `_.property` callback shorthand |
|
6900 * _.pluck(_.reject(users, 'active'), 'user'); |
|
6901 * // => ['barney'] |
|
6902 */ |
|
6903 function reject(collection, predicate, thisArg) { |
|
6904 var func = isArray(collection) ? arrayFilter : baseFilter; |
|
6905 predicate = getCallback(predicate, thisArg, 3); |
|
6906 return func(collection, function(value, index, collection) { |
|
6907 return !predicate(value, index, collection); |
|
6908 }); |
|
6909 } |
|
6910 |
|
6911 /** |
|
6912 * Gets a random element or `n` random elements from a collection. |
|
6913 * |
|
6914 * @static |
|
6915 * @memberOf _ |
|
6916 * @category Collection |
|
6917 * @param {Array|Object|string} collection The collection to sample. |
|
6918 * @param {number} [n] The number of elements to sample. |
|
6919 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
6920 * @returns {*} Returns the random sample(s). |
|
6921 * @example |
|
6922 * |
|
6923 * _.sample([1, 2, 3, 4]); |
|
6924 * // => 2 |
|
6925 * |
|
6926 * _.sample([1, 2, 3, 4], 2); |
|
6927 * // => [3, 1] |
|
6928 */ |
|
6929 function sample(collection, n, guard) { |
|
6930 if (guard ? isIterateeCall(collection, n, guard) : n == null) { |
|
6931 collection = toIterable(collection); |
|
6932 var length = collection.length; |
|
6933 return length > 0 ? collection[baseRandom(0, length - 1)] : undefined; |
|
6934 } |
|
6935 var index = -1, |
|
6936 result = toArray(collection), |
|
6937 length = result.length, |
|
6938 lastIndex = length - 1; |
|
6939 |
|
6940 n = nativeMin(n < 0 ? 0 : (+n || 0), length); |
|
6941 while (++index < n) { |
|
6942 var rand = baseRandom(index, lastIndex), |
|
6943 value = result[rand]; |
|
6944 |
|
6945 result[rand] = result[index]; |
|
6946 result[index] = value; |
|
6947 } |
|
6948 result.length = n; |
|
6949 return result; |
|
6950 } |
|
6951 |
|
6952 /** |
|
6953 * Creates an array of shuffled values, using a version of the |
|
6954 * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). |
|
6955 * |
|
6956 * @static |
|
6957 * @memberOf _ |
|
6958 * @category Collection |
|
6959 * @param {Array|Object|string} collection The collection to shuffle. |
|
6960 * @returns {Array} Returns the new shuffled array. |
|
6961 * @example |
|
6962 * |
|
6963 * _.shuffle([1, 2, 3, 4]); |
|
6964 * // => [4, 1, 3, 2] |
|
6965 */ |
|
6966 function shuffle(collection) { |
|
6967 return sample(collection, POSITIVE_INFINITY); |
|
6968 } |
|
6969 |
|
6970 /** |
|
6971 * Gets the size of `collection` by returning its length for array-like |
|
6972 * values or the number of own enumerable properties for objects. |
|
6973 * |
|
6974 * @static |
|
6975 * @memberOf _ |
|
6976 * @category Collection |
|
6977 * @param {Array|Object|string} collection The collection to inspect. |
|
6978 * @returns {number} Returns the size of `collection`. |
|
6979 * @example |
|
6980 * |
|
6981 * _.size([1, 2, 3]); |
|
6982 * // => 3 |
|
6983 * |
|
6984 * _.size({ 'a': 1, 'b': 2 }); |
|
6985 * // => 2 |
|
6986 * |
|
6987 * _.size('pebbles'); |
|
6988 * // => 7 |
|
6989 */ |
|
6990 function size(collection) { |
|
6991 var length = collection ? getLength(collection) : 0; |
|
6992 return isLength(length) ? length : keys(collection).length; |
|
6993 } |
|
6994 |
|
6995 /** |
|
6996 * Checks if `predicate` returns truthy for **any** element of `collection`. |
|
6997 * The function returns as soon as it finds a passing value and does not iterate |
|
6998 * over the entire collection. The predicate is bound to `thisArg` and invoked |
|
6999 * with three arguments: (value, index|key, collection). |
|
7000 * |
|
7001 * If a property name is provided for `predicate` the created `_.property` |
|
7002 * style callback returns the property value of the given element. |
|
7003 * |
|
7004 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
7005 * style callback returns `true` for elements that have a matching property |
|
7006 * value, else `false`. |
|
7007 * |
|
7008 * If an object is provided for `predicate` the created `_.matches` style |
|
7009 * callback returns `true` for elements that have the properties of the given |
|
7010 * object, else `false`. |
|
7011 * |
|
7012 * @static |
|
7013 * @memberOf _ |
|
7014 * @alias any |
|
7015 * @category Collection |
|
7016 * @param {Array|Object|string} collection The collection to iterate over. |
|
7017 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
7018 * per iteration. |
|
7019 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
7020 * @returns {boolean} Returns `true` if any element passes the predicate check, |
|
7021 * else `false`. |
|
7022 * @example |
|
7023 * |
|
7024 * _.some([null, 0, 'yes', false], Boolean); |
|
7025 * // => true |
|
7026 * |
|
7027 * var users = [ |
|
7028 * { 'user': 'barney', 'active': true }, |
|
7029 * { 'user': 'fred', 'active': false } |
|
7030 * ]; |
|
7031 * |
|
7032 * // using the `_.matches` callback shorthand |
|
7033 * _.some(users, { 'user': 'barney', 'active': false }); |
|
7034 * // => false |
|
7035 * |
|
7036 * // using the `_.matchesProperty` callback shorthand |
|
7037 * _.some(users, 'active', false); |
|
7038 * // => true |
|
7039 * |
|
7040 * // using the `_.property` callback shorthand |
|
7041 * _.some(users, 'active'); |
|
7042 * // => true |
|
7043 */ |
|
7044 function some(collection, predicate, thisArg) { |
|
7045 var func = isArray(collection) ? arraySome : baseSome; |
|
7046 if (thisArg && isIterateeCall(collection, predicate, thisArg)) { |
|
7047 predicate = undefined; |
|
7048 } |
|
7049 if (typeof predicate != 'function' || thisArg !== undefined) { |
|
7050 predicate = getCallback(predicate, thisArg, 3); |
|
7051 } |
|
7052 return func(collection, predicate); |
|
7053 } |
|
7054 |
|
7055 /** |
|
7056 * Creates an array of elements, sorted in ascending order by the results of |
|
7057 * running each element in a collection through `iteratee`. This method performs |
|
7058 * a stable sort, that is, it preserves the original sort order of equal elements. |
|
7059 * The `iteratee` is bound to `thisArg` and invoked with three arguments: |
|
7060 * (value, index|key, collection). |
|
7061 * |
|
7062 * If a property name is provided for `iteratee` the created `_.property` |
|
7063 * style callback returns the property value of the given element. |
|
7064 * |
|
7065 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
7066 * style callback returns `true` for elements that have a matching property |
|
7067 * value, else `false`. |
|
7068 * |
|
7069 * If an object is provided for `iteratee` the created `_.matches` style |
|
7070 * callback returns `true` for elements that have the properties of the given |
|
7071 * object, else `false`. |
|
7072 * |
|
7073 * @static |
|
7074 * @memberOf _ |
|
7075 * @category Collection |
|
7076 * @param {Array|Object|string} collection The collection to iterate over. |
|
7077 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
7078 * per iteration. |
|
7079 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
7080 * @returns {Array} Returns the new sorted array. |
|
7081 * @example |
|
7082 * |
|
7083 * _.sortBy([1, 2, 3], function(n) { |
|
7084 * return Math.sin(n); |
|
7085 * }); |
|
7086 * // => [3, 1, 2] |
|
7087 * |
|
7088 * _.sortBy([1, 2, 3], function(n) { |
|
7089 * return this.sin(n); |
|
7090 * }, Math); |
|
7091 * // => [3, 1, 2] |
|
7092 * |
|
7093 * var users = [ |
|
7094 * { 'user': 'fred' }, |
|
7095 * { 'user': 'pebbles' }, |
|
7096 * { 'user': 'barney' } |
|
7097 * ]; |
|
7098 * |
|
7099 * // using the `_.property` callback shorthand |
|
7100 * _.pluck(_.sortBy(users, 'user'), 'user'); |
|
7101 * // => ['barney', 'fred', 'pebbles'] |
|
7102 */ |
|
7103 function sortBy(collection, iteratee, thisArg) { |
|
7104 if (collection == null) { |
|
7105 return []; |
|
7106 } |
|
7107 if (thisArg && isIterateeCall(collection, iteratee, thisArg)) { |
|
7108 iteratee = undefined; |
|
7109 } |
|
7110 var index = -1; |
|
7111 iteratee = getCallback(iteratee, thisArg, 3); |
|
7112 |
|
7113 var result = baseMap(collection, function(value, key, collection) { |
|
7114 return { 'criteria': iteratee(value, key, collection), 'index': ++index, 'value': value }; |
|
7115 }); |
|
7116 return baseSortBy(result, compareAscending); |
|
7117 } |
|
7118 |
|
7119 /** |
|
7120 * This method is like `_.sortBy` except that it can sort by multiple iteratees |
|
7121 * or property names. |
|
7122 * |
|
7123 * If a property name is provided for an iteratee the created `_.property` |
|
7124 * style callback returns the property value of the given element. |
|
7125 * |
|
7126 * If an object is provided for an iteratee the created `_.matches` style |
|
7127 * callback returns `true` for elements that have the properties of the given |
|
7128 * object, else `false`. |
|
7129 * |
|
7130 * @static |
|
7131 * @memberOf _ |
|
7132 * @category Collection |
|
7133 * @param {Array|Object|string} collection The collection to iterate over. |
|
7134 * @param {...(Function|Function[]|Object|Object[]|string|string[])} iteratees |
|
7135 * The iteratees to sort by, specified as individual values or arrays of values. |
|
7136 * @returns {Array} Returns the new sorted array. |
|
7137 * @example |
|
7138 * |
|
7139 * var users = [ |
|
7140 * { 'user': 'fred', 'age': 48 }, |
|
7141 * { 'user': 'barney', 'age': 36 }, |
|
7142 * { 'user': 'fred', 'age': 42 }, |
|
7143 * { 'user': 'barney', 'age': 34 } |
|
7144 * ]; |
|
7145 * |
|
7146 * _.map(_.sortByAll(users, ['user', 'age']), _.values); |
|
7147 * // => [['barney', 34], ['barney', 36], ['fred', 42], ['fred', 48]] |
|
7148 * |
|
7149 * _.map(_.sortByAll(users, 'user', function(chr) { |
|
7150 * return Math.floor(chr.age / 10); |
|
7151 * }), _.values); |
|
7152 * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
|
7153 */ |
|
7154 var sortByAll = restParam(function(collection, iteratees) { |
|
7155 if (collection == null) { |
|
7156 return []; |
|
7157 } |
|
7158 var guard = iteratees[2]; |
|
7159 if (guard && isIterateeCall(iteratees[0], iteratees[1], guard)) { |
|
7160 iteratees.length = 1; |
|
7161 } |
|
7162 return baseSortByOrder(collection, baseFlatten(iteratees), []); |
|
7163 }); |
|
7164 |
|
7165 /** |
|
7166 * This method is like `_.sortByAll` except that it allows specifying the |
|
7167 * sort orders of the iteratees to sort by. If `orders` is unspecified, all |
|
7168 * values are sorted in ascending order. Otherwise, a value is sorted in |
|
7169 * ascending order if its corresponding order is "asc", and descending if "desc". |
|
7170 * |
|
7171 * If a property name is provided for an iteratee the created `_.property` |
|
7172 * style callback returns the property value of the given element. |
|
7173 * |
|
7174 * If an object is provided for an iteratee the created `_.matches` style |
|
7175 * callback returns `true` for elements that have the properties of the given |
|
7176 * object, else `false`. |
|
7177 * |
|
7178 * @static |
|
7179 * @memberOf _ |
|
7180 * @category Collection |
|
7181 * @param {Array|Object|string} collection The collection to iterate over. |
|
7182 * @param {Function[]|Object[]|string[]} iteratees The iteratees to sort by. |
|
7183 * @param {boolean[]} [orders] The sort orders of `iteratees`. |
|
7184 * @param- {Object} [guard] Enables use as a callback for functions like `_.reduce`. |
|
7185 * @returns {Array} Returns the new sorted array. |
|
7186 * @example |
|
7187 * |
|
7188 * var users = [ |
|
7189 * { 'user': 'fred', 'age': 48 }, |
|
7190 * { 'user': 'barney', 'age': 34 }, |
|
7191 * { 'user': 'fred', 'age': 42 }, |
|
7192 * { 'user': 'barney', 'age': 36 } |
|
7193 * ]; |
|
7194 * |
|
7195 * // sort by `user` in ascending order and by `age` in descending order |
|
7196 * _.map(_.sortByOrder(users, ['user', 'age'], ['asc', 'desc']), _.values); |
|
7197 * // => [['barney', 36], ['barney', 34], ['fred', 48], ['fred', 42]] |
|
7198 */ |
|
7199 function sortByOrder(collection, iteratees, orders, guard) { |
|
7200 if (collection == null) { |
|
7201 return []; |
|
7202 } |
|
7203 if (guard && isIterateeCall(iteratees, orders, guard)) { |
|
7204 orders = undefined; |
|
7205 } |
|
7206 if (!isArray(iteratees)) { |
|
7207 iteratees = iteratees == null ? [] : [iteratees]; |
|
7208 } |
|
7209 if (!isArray(orders)) { |
|
7210 orders = orders == null ? [] : [orders]; |
|
7211 } |
|
7212 return baseSortByOrder(collection, iteratees, orders); |
|
7213 } |
|
7214 |
|
7215 /** |
|
7216 * Performs a deep comparison between each element in `collection` and the |
|
7217 * source object, returning an array of all elements that have equivalent |
|
7218 * property values. |
|
7219 * |
|
7220 * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
|
7221 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
|
7222 * their own, not inherited, enumerable properties. For comparing a single |
|
7223 * own or inherited property value see `_.matchesProperty`. |
|
7224 * |
|
7225 * @static |
|
7226 * @memberOf _ |
|
7227 * @category Collection |
|
7228 * @param {Array|Object|string} collection The collection to search. |
|
7229 * @param {Object} source The object of property values to match. |
|
7230 * @returns {Array} Returns the new filtered array. |
|
7231 * @example |
|
7232 * |
|
7233 * var users = [ |
|
7234 * { 'user': 'barney', 'age': 36, 'active': false, 'pets': ['hoppy'] }, |
|
7235 * { 'user': 'fred', 'age': 40, 'active': true, 'pets': ['baby puss', 'dino'] } |
|
7236 * ]; |
|
7237 * |
|
7238 * _.pluck(_.where(users, { 'age': 36, 'active': false }), 'user'); |
|
7239 * // => ['barney'] |
|
7240 * |
|
7241 * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); |
|
7242 * // => ['fred'] |
|
7243 */ |
|
7244 function where(collection, source) { |
|
7245 return filter(collection, baseMatches(source)); |
|
7246 } |
|
7247 |
|
7248 /*------------------------------------------------------------------------*/ |
|
7249 |
|
7250 /** |
|
7251 * Gets the number of milliseconds that have elapsed since the Unix epoch |
|
7252 * (1 January 1970 00:00:00 UTC). |
|
7253 * |
|
7254 * @static |
|
7255 * @memberOf _ |
|
7256 * @category Date |
|
7257 * @example |
|
7258 * |
|
7259 * _.defer(function(stamp) { |
|
7260 * console.log(_.now() - stamp); |
|
7261 * }, _.now()); |
|
7262 * // => logs the number of milliseconds it took for the deferred function to be invoked |
|
7263 */ |
|
7264 var now = nativeNow || function() { |
|
7265 return new Date().getTime(); |
|
7266 }; |
|
7267 |
|
7268 /*------------------------------------------------------------------------*/ |
|
7269 |
|
7270 /** |
|
7271 * The opposite of `_.before`; this method creates a function that invokes |
|
7272 * `func` once it's called `n` or more times. |
|
7273 * |
|
7274 * @static |
|
7275 * @memberOf _ |
|
7276 * @category Function |
|
7277 * @param {number} n The number of calls before `func` is invoked. |
5123 * @param {Function} func The function to restrict. |
7278 * @param {Function} func The function to restrict. |
5124 * @returns {Function} Returns the new restricted function. |
7279 * @returns {Function} Returns the new restricted function. |
5125 * @example |
7280 * @example |
5126 * |
7281 * |
5127 * var saves = ['profile', 'settings']; |
7282 * var saves = ['profile', 'settings']; |
5128 * |
7283 * |
5129 * var done = _.after(saves.length, function() { |
7284 * var done = _.after(saves.length, function() { |
5130 * console.log('Done saving!'); |
7285 * console.log('done saving!'); |
5131 * }); |
7286 * }); |
5132 * |
7287 * |
5133 * _.forEach(saves, function(type) { |
7288 * _.forEach(saves, function(type) { |
5134 * asyncSave({ 'type': type, 'complete': done }); |
7289 * asyncSave({ 'type': type, 'complete': done }); |
5135 * }); |
7290 * }); |
5136 * // => logs 'Done saving!', after all saves have completed |
7291 * // => logs 'done saving!' after the two async saves have completed |
5137 */ |
7292 */ |
5138 function after(n, func) { |
7293 function after(n, func) { |
5139 if (!isFunction(func)) { |
7294 if (typeof func != 'function') { |
5140 throw new TypeError; |
7295 if (typeof n == 'function') { |
5141 } |
7296 var temp = n; |
|
7297 n = func; |
|
7298 func = temp; |
|
7299 } else { |
|
7300 throw new TypeError(FUNC_ERROR_TEXT); |
|
7301 } |
|
7302 } |
|
7303 n = nativeIsFinite(n = +n) ? n : 0; |
5142 return function() { |
7304 return function() { |
5143 if (--n < 1) { |
7305 if (--n < 1) { |
5144 return func.apply(this, arguments); |
7306 return func.apply(this, arguments); |
5145 } |
7307 } |
5146 }; |
7308 }; |
5147 } |
7309 } |
5148 |
7310 |
5149 /** |
7311 /** |
5150 * Creates a function that, when called, invokes `func` with the `this` |
7312 * Creates a function that accepts up to `n` arguments ignoring any |
5151 * binding of `thisArg` and prepends any additional `bind` arguments to those |
7313 * additional arguments. |
5152 * provided to the bound function. |
7314 * |
5153 * |
7315 * @static |
5154 * @static |
7316 * @memberOf _ |
5155 * @memberOf _ |
7317 * @category Function |
5156 * @category Functions |
7318 * @param {Function} func The function to cap arguments for. |
|
7319 * @param {number} [n=func.length] The arity cap. |
|
7320 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
7321 * @returns {Function} Returns the new function. |
|
7322 * @example |
|
7323 * |
|
7324 * _.map(['6', '8', '10'], _.ary(parseInt, 1)); |
|
7325 * // => [6, 8, 10] |
|
7326 */ |
|
7327 function ary(func, n, guard) { |
|
7328 if (guard && isIterateeCall(func, n, guard)) { |
|
7329 n = undefined; |
|
7330 } |
|
7331 n = (func && n == null) ? func.length : nativeMax(+n || 0, 0); |
|
7332 return createWrapper(func, ARY_FLAG, undefined, undefined, undefined, undefined, n); |
|
7333 } |
|
7334 |
|
7335 /** |
|
7336 * Creates a function that invokes `func`, with the `this` binding and arguments |
|
7337 * of the created function, while it's called less than `n` times. Subsequent |
|
7338 * calls to the created function return the result of the last `func` invocation. |
|
7339 * |
|
7340 * @static |
|
7341 * @memberOf _ |
|
7342 * @category Function |
|
7343 * @param {number} n The number of calls at which `func` is no longer invoked. |
|
7344 * @param {Function} func The function to restrict. |
|
7345 * @returns {Function} Returns the new restricted function. |
|
7346 * @example |
|
7347 * |
|
7348 * jQuery('#add').on('click', _.before(5, addContactToList)); |
|
7349 * // => allows adding up to 4 contacts to the list |
|
7350 */ |
|
7351 function before(n, func) { |
|
7352 var result; |
|
7353 if (typeof func != 'function') { |
|
7354 if (typeof n == 'function') { |
|
7355 var temp = n; |
|
7356 n = func; |
|
7357 func = temp; |
|
7358 } else { |
|
7359 throw new TypeError(FUNC_ERROR_TEXT); |
|
7360 } |
|
7361 } |
|
7362 return function() { |
|
7363 if (--n > 0) { |
|
7364 result = func.apply(this, arguments); |
|
7365 } |
|
7366 if (n <= 1) { |
|
7367 func = undefined; |
|
7368 } |
|
7369 return result; |
|
7370 }; |
|
7371 } |
|
7372 |
|
7373 /** |
|
7374 * Creates a function that invokes `func` with the `this` binding of `thisArg` |
|
7375 * and prepends any additional `_.bind` arguments to those provided to the |
|
7376 * bound function. |
|
7377 * |
|
7378 * The `_.bind.placeholder` value, which defaults to `_` in monolithic builds, |
|
7379 * may be used as a placeholder for partially applied arguments. |
|
7380 * |
|
7381 * **Note:** Unlike native `Function#bind` this method does not set the "length" |
|
7382 * property of bound functions. |
|
7383 * |
|
7384 * @static |
|
7385 * @memberOf _ |
|
7386 * @category Function |
5157 * @param {Function} func The function to bind. |
7387 * @param {Function} func The function to bind. |
5158 * @param {*} [thisArg] The `this` binding of `func`. |
7388 * @param {*} thisArg The `this` binding of `func`. |
5159 * @param {...*} [arg] Arguments to be partially applied. |
7389 * @param {...*} [partials] The arguments to be partially applied. |
5160 * @returns {Function} Returns the new bound function. |
7390 * @returns {Function} Returns the new bound function. |
5161 * @example |
7391 * @example |
5162 * |
7392 * |
5163 * var func = function(greeting) { |
7393 * var greet = function(greeting, punctuation) { |
5164 * return greeting + ' ' + this.name; |
7394 * return greeting + ' ' + this.user + punctuation; |
5165 * }; |
7395 * }; |
5166 * |
7396 * |
5167 * func = _.bind(func, { 'name': 'fred' }, 'hi'); |
7397 * var object = { 'user': 'fred' }; |
5168 * func(); |
7398 * |
5169 * // => 'hi fred' |
7399 * var bound = _.bind(greet, object, 'hi'); |
5170 */ |
7400 * bound('!'); |
5171 function bind(func, thisArg) { |
7401 * // => 'hi fred!' |
5172 return arguments.length > 2 |
7402 * |
5173 ? createWrapper(func, 17, slice(arguments, 2), null, thisArg) |
7403 * // using placeholders |
5174 : createWrapper(func, 1, null, null, thisArg); |
7404 * var bound = _.bind(greet, object, _, '!'); |
5175 } |
7405 * bound('hi'); |
|
7406 * // => 'hi fred!' |
|
7407 */ |
|
7408 var bind = restParam(function(func, thisArg, partials) { |
|
7409 var bitmask = BIND_FLAG; |
|
7410 if (partials.length) { |
|
7411 var holders = replaceHolders(partials, bind.placeholder); |
|
7412 bitmask |= PARTIAL_FLAG; |
|
7413 } |
|
7414 return createWrapper(func, bitmask, thisArg, partials, holders); |
|
7415 }); |
5176 |
7416 |
5177 /** |
7417 /** |
5178 * Binds methods of an object to the object itself, overwriting the existing |
7418 * Binds methods of an object to the object itself, overwriting the existing |
5179 * method. Method names may be specified as individual arguments or as arrays |
7419 * method. Method names may be specified as individual arguments or as arrays |
5180 * of method names. If no method names are provided all the function properties |
7420 * of method names. If no method names are provided all enumerable function |
5181 * of `object` will be bound. |
7421 * properties, own and inherited, of `object` are bound. |
5182 * |
7422 * |
5183 * @static |
7423 * **Note:** This method does not set the "length" property of bound functions. |
5184 * @memberOf _ |
7424 * |
5185 * @category Functions |
7425 * @static |
|
7426 * @memberOf _ |
|
7427 * @category Function |
5186 * @param {Object} object The object to bind and assign the bound methods to. |
7428 * @param {Object} object The object to bind and assign the bound methods to. |
5187 * @param {...string} [methodName] The object method names to |
7429 * @param {...(string|string[])} [methodNames] The object method names to bind, |
5188 * bind, specified as individual method names or arrays of method names. |
7430 * specified as individual method names or arrays of method names. |
5189 * @returns {Object} Returns `object`. |
7431 * @returns {Object} Returns `object`. |
5190 * @example |
7432 * @example |
5191 * |
7433 * |
5192 * var view = { |
7434 * var view = { |
5193 * 'label': 'docs', |
7435 * 'label': 'docs', |
5194 * 'onClick': function() { console.log('clicked ' + this.label); } |
7436 * 'onClick': function() { |
|
7437 * console.log('clicked ' + this.label); |
|
7438 * } |
5195 * }; |
7439 * }; |
5196 * |
7440 * |
5197 * _.bindAll(view); |
7441 * _.bindAll(view); |
5198 * jQuery('#docs').on('click', view.onClick); |
7442 * jQuery('#docs').on('click', view.onClick); |
5199 * // => logs 'clicked docs', when the button is clicked |
7443 * // => logs 'clicked docs' when the element is clicked |
5200 */ |
7444 */ |
5201 function bindAll(object) { |
7445 var bindAll = restParam(function(object, methodNames) { |
5202 var funcs = arguments.length > 1 ? baseFlatten(arguments, true, false, 1) : functions(object), |
7446 methodNames = methodNames.length ? baseFlatten(methodNames) : functions(object); |
5203 index = -1, |
7447 |
5204 length = funcs.length; |
7448 var index = -1, |
|
7449 length = methodNames.length; |
5205 |
7450 |
5206 while (++index < length) { |
7451 while (++index < length) { |
5207 var key = funcs[index]; |
7452 var key = methodNames[index]; |
5208 object[key] = createWrapper(object[key], 1, null, null, object); |
7453 object[key] = createWrapper(object[key], BIND_FLAG, object); |
5209 } |
7454 } |
5210 return object; |
7455 return object; |
5211 } |
7456 }); |
5212 |
7457 |
5213 /** |
7458 /** |
5214 * Creates a function that, when called, invokes the method at `object[key]` |
7459 * Creates a function that invokes the method at `object[key]` and prepends |
5215 * and prepends any additional `bindKey` arguments to those provided to the bound |
7460 * any additional `_.bindKey` arguments to those provided to the bound function. |
5216 * function. This method differs from `_.bind` by allowing bound functions to |
7461 * |
5217 * reference methods that will be redefined or don't yet exist. |
7462 * This method differs from `_.bind` by allowing bound functions to reference |
5218 * See http://michaux.ca/articles/lazy-function-definition-pattern. |
7463 * methods that may be redefined or don't yet exist. |
5219 * |
7464 * See [Peter Michaux's article](http://peter.michaux.ca/articles/lazy-function-definition-pattern) |
5220 * @static |
7465 * for more details. |
5221 * @memberOf _ |
7466 * |
5222 * @category Functions |
7467 * The `_.bindKey.placeholder` value, which defaults to `_` in monolithic |
|
7468 * builds, may be used as a placeholder for partially applied arguments. |
|
7469 * |
|
7470 * @static |
|
7471 * @memberOf _ |
|
7472 * @category Function |
5223 * @param {Object} object The object the method belongs to. |
7473 * @param {Object} object The object the method belongs to. |
5224 * @param {string} key The key of the method. |
7474 * @param {string} key The key of the method. |
5225 * @param {...*} [arg] Arguments to be partially applied. |
7475 * @param {...*} [partials] The arguments to be partially applied. |
5226 * @returns {Function} Returns the new bound function. |
7476 * @returns {Function} Returns the new bound function. |
5227 * @example |
7477 * @example |
5228 * |
7478 * |
5229 * var object = { |
7479 * var object = { |
5230 * 'name': 'fred', |
7480 * 'user': 'fred', |
5231 * 'greet': function(greeting) { |
7481 * 'greet': function(greeting, punctuation) { |
5232 * return greeting + ' ' + this.name; |
7482 * return greeting + ' ' + this.user + punctuation; |
5233 * } |
7483 * } |
5234 * }; |
7484 * }; |
5235 * |
7485 * |
5236 * var func = _.bindKey(object, 'greet', 'hi'); |
7486 * var bound = _.bindKey(object, 'greet', 'hi'); |
5237 * func(); |
7487 * bound('!'); |
5238 * // => 'hi fred' |
7488 * // => 'hi fred!' |
5239 * |
7489 * |
5240 * object.greet = function(greeting) { |
7490 * object.greet = function(greeting, punctuation) { |
5241 * return greeting + 'ya ' + this.name + '!'; |
7491 * return greeting + 'ya ' + this.user + punctuation; |
5242 * }; |
7492 * }; |
5243 * |
7493 * |
5244 * func(); |
7494 * bound('!'); |
5245 * // => 'hiya fred!' |
7495 * // => 'hiya fred!' |
5246 */ |
7496 * |
5247 function bindKey(object, key) { |
7497 * // using placeholders |
5248 return arguments.length > 2 |
7498 * var bound = _.bindKey(object, 'greet', _, '!'); |
5249 ? createWrapper(key, 19, slice(arguments, 2), null, object) |
7499 * bound('hi'); |
5250 : createWrapper(key, 3, null, null, object); |
7500 * // => 'hiya fred!' |
5251 } |
7501 */ |
5252 |
7502 var bindKey = restParam(function(object, key, partials) { |
5253 /** |
7503 var bitmask = BIND_FLAG | BIND_KEY_FLAG; |
5254 * Creates a function that is the composition of the provided functions, |
7504 if (partials.length) { |
5255 * where each function consumes the return value of the function that follows. |
7505 var holders = replaceHolders(partials, bindKey.placeholder); |
5256 * For example, composing the functions `f()`, `g()`, and `h()` produces `f(g(h()))`. |
7506 bitmask |= PARTIAL_FLAG; |
5257 * Each function is executed with the `this` binding of the composed function. |
7507 } |
5258 * |
7508 return createWrapper(key, bitmask, object, partials, holders); |
5259 * @static |
7509 }); |
5260 * @memberOf _ |
7510 |
5261 * @category Functions |
7511 /** |
5262 * @param {...Function} [func] Functions to compose. |
7512 * Creates a function that accepts one or more arguments of `func` that when |
5263 * @returns {Function} Returns the new composed function. |
7513 * called either invokes `func` returning its result, if all `func` arguments |
5264 * @example |
|
5265 * |
|
5266 * var realNameMap = { |
|
5267 * 'pebbles': 'penelope' |
|
5268 * }; |
|
5269 * |
|
5270 * var format = function(name) { |
|
5271 * name = realNameMap[name.toLowerCase()] || name; |
|
5272 * return name.charAt(0).toUpperCase() + name.slice(1).toLowerCase(); |
|
5273 * }; |
|
5274 * |
|
5275 * var greet = function(formatted) { |
|
5276 * return 'Hiya ' + formatted + '!'; |
|
5277 * }; |
|
5278 * |
|
5279 * var welcome = _.compose(greet, format); |
|
5280 * welcome('pebbles'); |
|
5281 * // => 'Hiya Penelope!' |
|
5282 */ |
|
5283 function compose() { |
|
5284 var funcs = arguments, |
|
5285 length = funcs.length; |
|
5286 |
|
5287 while (length--) { |
|
5288 if (!isFunction(funcs[length])) { |
|
5289 throw new TypeError; |
|
5290 } |
|
5291 } |
|
5292 return function() { |
|
5293 var args = arguments, |
|
5294 length = funcs.length; |
|
5295 |
|
5296 while (length--) { |
|
5297 args = [funcs[length].apply(this, args)]; |
|
5298 } |
|
5299 return args[0]; |
|
5300 }; |
|
5301 } |
|
5302 |
|
5303 /** |
|
5304 * Creates a function which accepts one or more arguments of `func` that when |
|
5305 * invoked either executes `func` returning its result, if all `func` arguments |
|
5306 * have been provided, or returns a function that accepts one or more of the |
7514 * have been provided, or returns a function that accepts one or more of the |
5307 * remaining `func` arguments, and so on. The arity of `func` can be specified |
7515 * remaining `func` arguments, and so on. The arity of `func` may be specified |
5308 * if `func.length` is not sufficient. |
7516 * if `func.length` is not sufficient. |
5309 * |
7517 * |
5310 * @static |
7518 * The `_.curry.placeholder` value, which defaults to `_` in monolithic builds, |
5311 * @memberOf _ |
7519 * may be used as a placeholder for provided arguments. |
5312 * @category Functions |
7520 * |
|
7521 * **Note:** This method does not set the "length" property of curried functions. |
|
7522 * |
|
7523 * @static |
|
7524 * @memberOf _ |
|
7525 * @category Function |
5313 * @param {Function} func The function to curry. |
7526 * @param {Function} func The function to curry. |
5314 * @param {number} [arity=func.length] The arity of `func`. |
7527 * @param {number} [arity=func.length] The arity of `func`. |
|
7528 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
5315 * @returns {Function} Returns the new curried function. |
7529 * @returns {Function} Returns the new curried function. |
5316 * @example |
7530 * @example |
5317 * |
7531 * |
5318 * var curried = _.curry(function(a, b, c) { |
7532 * var abc = function(a, b, c) { |
5319 * console.log(a + b + c); |
7533 * return [a, b, c]; |
5320 * }); |
7534 * }; |
|
7535 * |
|
7536 * var curried = _.curry(abc); |
5321 * |
7537 * |
5322 * curried(1)(2)(3); |
7538 * curried(1)(2)(3); |
5323 * // => 6 |
7539 * // => [1, 2, 3] |
5324 * |
7540 * |
5325 * curried(1, 2)(3); |
7541 * curried(1, 2)(3); |
5326 * // => 6 |
7542 * // => [1, 2, 3] |
5327 * |
7543 * |
5328 * curried(1, 2, 3); |
7544 * curried(1, 2, 3); |
5329 * // => 6 |
7545 * // => [1, 2, 3] |
5330 */ |
7546 * |
5331 function curry(func, arity) { |
7547 * // using placeholders |
5332 arity = typeof arity == 'number' ? arity : (+arity || func.length); |
7548 * curried(1)(_, 3)(2); |
5333 return createWrapper(func, 4, null, null, null, arity); |
7549 * // => [1, 2, 3] |
5334 } |
7550 */ |
5335 |
7551 var curry = createCurry(CURRY_FLAG); |
5336 /** |
7552 |
5337 * Creates a function that will delay the execution of `func` until after |
7553 /** |
5338 * `wait` milliseconds have elapsed since the last time it was invoked. |
7554 * This method is like `_.curry` except that arguments are applied to `func` |
5339 * Provide an options object to indicate that `func` should be invoked on |
7555 * in the manner of `_.partialRight` instead of `_.partial`. |
5340 * the leading and/or trailing edge of the `wait` timeout. Subsequent calls |
7556 * |
5341 * to the debounced function will return the result of the last `func` call. |
7557 * The `_.curryRight.placeholder` value, which defaults to `_` in monolithic |
5342 * |
7558 * builds, may be used as a placeholder for provided arguments. |
5343 * Note: If `leading` and `trailing` options are `true` `func` will be called |
7559 * |
|
7560 * **Note:** This method does not set the "length" property of curried functions. |
|
7561 * |
|
7562 * @static |
|
7563 * @memberOf _ |
|
7564 * @category Function |
|
7565 * @param {Function} func The function to curry. |
|
7566 * @param {number} [arity=func.length] The arity of `func`. |
|
7567 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
7568 * @returns {Function} Returns the new curried function. |
|
7569 * @example |
|
7570 * |
|
7571 * var abc = function(a, b, c) { |
|
7572 * return [a, b, c]; |
|
7573 * }; |
|
7574 * |
|
7575 * var curried = _.curryRight(abc); |
|
7576 * |
|
7577 * curried(3)(2)(1); |
|
7578 * // => [1, 2, 3] |
|
7579 * |
|
7580 * curried(2, 3)(1); |
|
7581 * // => [1, 2, 3] |
|
7582 * |
|
7583 * curried(1, 2, 3); |
|
7584 * // => [1, 2, 3] |
|
7585 * |
|
7586 * // using placeholders |
|
7587 * curried(3)(1, _)(2); |
|
7588 * // => [1, 2, 3] |
|
7589 */ |
|
7590 var curryRight = createCurry(CURRY_RIGHT_FLAG); |
|
7591 |
|
7592 /** |
|
7593 * Creates a debounced function that delays invoking `func` until after `wait` |
|
7594 * milliseconds have elapsed since the last time the debounced function was |
|
7595 * invoked. The debounced function comes with a `cancel` method to cancel |
|
7596 * delayed invocations. Provide an options object to indicate that `func` |
|
7597 * should be invoked on the leading and/or trailing edge of the `wait` timeout. |
|
7598 * Subsequent calls to the debounced function return the result of the last |
|
7599 * `func` invocation. |
|
7600 * |
|
7601 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked |
5344 * on the trailing edge of the timeout only if the the debounced function is |
7602 * on the trailing edge of the timeout only if the the debounced function is |
5345 * invoked more than once during the `wait` timeout. |
7603 * invoked more than once during the `wait` timeout. |
5346 * |
7604 * |
5347 * @static |
7605 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) |
5348 * @memberOf _ |
7606 * for details over the differences between `_.debounce` and `_.throttle`. |
5349 * @category Functions |
7607 * |
|
7608 * @static |
|
7609 * @memberOf _ |
|
7610 * @category Function |
5350 * @param {Function} func The function to debounce. |
7611 * @param {Function} func The function to debounce. |
5351 * @param {number} wait The number of milliseconds to delay. |
7612 * @param {number} [wait=0] The number of milliseconds to delay. |
5352 * @param {Object} [options] The options object. |
7613 * @param {Object} [options] The options object. |
5353 * @param {boolean} [options.leading=false] Specify execution on the leading edge of the timeout. |
7614 * @param {boolean} [options.leading=false] Specify invoking on the leading |
5354 * @param {number} [options.maxWait] The maximum time `func` is allowed to be delayed before it's called. |
7615 * edge of the timeout. |
5355 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. |
7616 * @param {number} [options.maxWait] The maximum time `func` is allowed to be |
|
7617 * delayed before it's invoked. |
|
7618 * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
|
7619 * edge of the timeout. |
5356 * @returns {Function} Returns the new debounced function. |
7620 * @returns {Function} Returns the new debounced function. |
5357 * @example |
7621 * @example |
5358 * |
7622 * |
5359 * // avoid costly calculations while the window size is in flux |
7623 * // avoid costly calculations while the window size is in flux |
5360 * var lazyLayout = _.debounce(calculateLayout, 150); |
7624 * jQuery(window).on('resize', _.debounce(calculateLayout, 150)); |
5361 * jQuery(window).on('resize', lazyLayout); |
7625 * |
5362 * |
7626 * // invoke `sendMail` when the click event is fired, debouncing subsequent calls |
5363 * // execute `sendMail` when the click event is fired, debouncing subsequent calls |
|
5364 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { |
7627 * jQuery('#postbox').on('click', _.debounce(sendMail, 300, { |
5365 * 'leading': true, |
7628 * 'leading': true, |
5366 * 'trailing': false |
7629 * 'trailing': false |
5367 * }); |
7630 * })); |
5368 * |
7631 * |
5369 * // ensure `batchLog` is executed once after 1 second of debounced calls |
7632 * // ensure `batchLog` is invoked once after 1 second of debounced calls |
5370 * var source = new EventSource('/stream'); |
7633 * var source = new EventSource('/stream'); |
5371 * source.addEventListener('message', _.debounce(batchLog, 250, { |
7634 * jQuery(source).on('message', _.debounce(batchLog, 250, { |
5372 * 'maxWait': 1000 |
7635 * 'maxWait': 1000 |
5373 * }, false); |
7636 * })); |
|
7637 * |
|
7638 * // cancel a debounced call |
|
7639 * var todoChanges = _.debounce(batchLog, 1000); |
|
7640 * Object.observe(models.todo, todoChanges); |
|
7641 * |
|
7642 * Object.observe(models, function(changes) { |
|
7643 * if (_.find(changes, { 'user': 'todo', 'type': 'delete'})) { |
|
7644 * todoChanges.cancel(); |
|
7645 * } |
|
7646 * }, ['delete']); |
|
7647 * |
|
7648 * // ...at some point `models.todo` is changed |
|
7649 * models.todo.completed = true; |
|
7650 * |
|
7651 * // ...before 1 second has passed `models.todo` is deleted |
|
7652 * // which cancels the debounced `todoChanges` call |
|
7653 * delete models.todo; |
5374 */ |
7654 */ |
5375 function debounce(func, wait, options) { |
7655 function debounce(func, wait, options) { |
5376 var args, |
7656 var args, |
5377 maxTimeoutId, |
7657 maxTimeoutId, |
5378 result, |
7658 result, |
5465 if (leadingCall) { |
7750 if (leadingCall) { |
5466 isCalled = true; |
7751 isCalled = true; |
5467 result = func.apply(thisArg, args); |
7752 result = func.apply(thisArg, args); |
5468 } |
7753 } |
5469 if (isCalled && !timeoutId && !maxTimeoutId) { |
7754 if (isCalled && !timeoutId && !maxTimeoutId) { |
5470 args = thisArg = null; |
7755 args = thisArg = undefined; |
5471 } |
7756 } |
|
7757 return result; |
|
7758 } |
|
7759 debounced.cancel = cancel; |
|
7760 return debounced; |
|
7761 } |
|
7762 |
|
7763 /** |
|
7764 * Defers invoking the `func` until the current call stack has cleared. Any |
|
7765 * additional arguments are provided to `func` when it's invoked. |
|
7766 * |
|
7767 * @static |
|
7768 * @memberOf _ |
|
7769 * @category Function |
|
7770 * @param {Function} func The function to defer. |
|
7771 * @param {...*} [args] The arguments to invoke the function with. |
|
7772 * @returns {number} Returns the timer id. |
|
7773 * @example |
|
7774 * |
|
7775 * _.defer(function(text) { |
|
7776 * console.log(text); |
|
7777 * }, 'deferred'); |
|
7778 * // logs 'deferred' after one or more milliseconds |
|
7779 */ |
|
7780 var defer = restParam(function(func, args) { |
|
7781 return baseDelay(func, 1, args); |
|
7782 }); |
|
7783 |
|
7784 /** |
|
7785 * Invokes `func` after `wait` milliseconds. Any additional arguments are |
|
7786 * provided to `func` when it's invoked. |
|
7787 * |
|
7788 * @static |
|
7789 * @memberOf _ |
|
7790 * @category Function |
|
7791 * @param {Function} func The function to delay. |
|
7792 * @param {number} wait The number of milliseconds to delay invocation. |
|
7793 * @param {...*} [args] The arguments to invoke the function with. |
|
7794 * @returns {number} Returns the timer id. |
|
7795 * @example |
|
7796 * |
|
7797 * _.delay(function(text) { |
|
7798 * console.log(text); |
|
7799 * }, 1000, 'later'); |
|
7800 * // => logs 'later' after one second |
|
7801 */ |
|
7802 var delay = restParam(function(func, wait, args) { |
|
7803 return baseDelay(func, wait, args); |
|
7804 }); |
|
7805 |
|
7806 /** |
|
7807 * Creates a function that returns the result of invoking the provided |
|
7808 * functions with the `this` binding of the created function, where each |
|
7809 * successive invocation is supplied the return value of the previous. |
|
7810 * |
|
7811 * @static |
|
7812 * @memberOf _ |
|
7813 * @category Function |
|
7814 * @param {...Function} [funcs] Functions to invoke. |
|
7815 * @returns {Function} Returns the new function. |
|
7816 * @example |
|
7817 * |
|
7818 * function square(n) { |
|
7819 * return n * n; |
|
7820 * } |
|
7821 * |
|
7822 * var addSquare = _.flow(_.add, square); |
|
7823 * addSquare(1, 2); |
|
7824 * // => 9 |
|
7825 */ |
|
7826 var flow = createFlow(); |
|
7827 |
|
7828 /** |
|
7829 * This method is like `_.flow` except that it creates a function that |
|
7830 * invokes the provided functions from right to left. |
|
7831 * |
|
7832 * @static |
|
7833 * @memberOf _ |
|
7834 * @alias backflow, compose |
|
7835 * @category Function |
|
7836 * @param {...Function} [funcs] Functions to invoke. |
|
7837 * @returns {Function} Returns the new function. |
|
7838 * @example |
|
7839 * |
|
7840 * function square(n) { |
|
7841 * return n * n; |
|
7842 * } |
|
7843 * |
|
7844 * var addSquare = _.flowRight(square, _.add); |
|
7845 * addSquare(1, 2); |
|
7846 * // => 9 |
|
7847 */ |
|
7848 var flowRight = createFlow(true); |
|
7849 |
|
7850 /** |
|
7851 * Creates a function that memoizes the result of `func`. If `resolver` is |
|
7852 * provided it determines the cache key for storing the result based on the |
|
7853 * arguments provided to the memoized function. By default, the first argument |
|
7854 * provided to the memoized function is coerced to a string and used as the |
|
7855 * cache key. The `func` is invoked with the `this` binding of the memoized |
|
7856 * function. |
|
7857 * |
|
7858 * **Note:** The cache is exposed as the `cache` property on the memoized |
|
7859 * function. Its creation may be customized by replacing the `_.memoize.Cache` |
|
7860 * constructor with one whose instances implement the [`Map`](http://ecma-international.org/ecma-262/6.0/#sec-properties-of-the-map-prototype-object) |
|
7861 * method interface of `get`, `has`, and `set`. |
|
7862 * |
|
7863 * @static |
|
7864 * @memberOf _ |
|
7865 * @category Function |
|
7866 * @param {Function} func The function to have its output memoized. |
|
7867 * @param {Function} [resolver] The function to resolve the cache key. |
|
7868 * @returns {Function} Returns the new memoizing function. |
|
7869 * @example |
|
7870 * |
|
7871 * var upperCase = _.memoize(function(string) { |
|
7872 * return string.toUpperCase(); |
|
7873 * }); |
|
7874 * |
|
7875 * upperCase('fred'); |
|
7876 * // => 'FRED' |
|
7877 * |
|
7878 * // modifying the result cache |
|
7879 * upperCase.cache.set('fred', 'BARNEY'); |
|
7880 * upperCase('fred'); |
|
7881 * // => 'BARNEY' |
|
7882 * |
|
7883 * // replacing `_.memoize.Cache` |
|
7884 * var object = { 'user': 'fred' }; |
|
7885 * var other = { 'user': 'barney' }; |
|
7886 * var identity = _.memoize(_.identity); |
|
7887 * |
|
7888 * identity(object); |
|
7889 * // => { 'user': 'fred' } |
|
7890 * identity(other); |
|
7891 * // => { 'user': 'fred' } |
|
7892 * |
|
7893 * _.memoize.Cache = WeakMap; |
|
7894 * var identity = _.memoize(_.identity); |
|
7895 * |
|
7896 * identity(object); |
|
7897 * // => { 'user': 'fred' } |
|
7898 * identity(other); |
|
7899 * // => { 'user': 'barney' } |
|
7900 */ |
|
7901 function memoize(func, resolver) { |
|
7902 if (typeof func != 'function' || (resolver && typeof resolver != 'function')) { |
|
7903 throw new TypeError(FUNC_ERROR_TEXT); |
|
7904 } |
|
7905 var memoized = function() { |
|
7906 var args = arguments, |
|
7907 key = resolver ? resolver.apply(this, args) : args[0], |
|
7908 cache = memoized.cache; |
|
7909 |
|
7910 if (cache.has(key)) { |
|
7911 return cache.get(key); |
|
7912 } |
|
7913 var result = func.apply(this, args); |
|
7914 memoized.cache = cache.set(key, result); |
5472 return result; |
7915 return result; |
5473 }; |
7916 }; |
5474 } |
7917 memoized.cache = new memoize.Cache; |
5475 |
|
5476 /** |
|
5477 * Defers executing the `func` function until the current call stack has cleared. |
|
5478 * Additional arguments will be provided to `func` when it is invoked. |
|
5479 * |
|
5480 * @static |
|
5481 * @memberOf _ |
|
5482 * @category Functions |
|
5483 * @param {Function} func The function to defer. |
|
5484 * @param {...*} [arg] Arguments to invoke the function with. |
|
5485 * @returns {number} Returns the timer id. |
|
5486 * @example |
|
5487 * |
|
5488 * _.defer(function(text) { console.log(text); }, 'deferred'); |
|
5489 * // logs 'deferred' after one or more milliseconds |
|
5490 */ |
|
5491 function defer(func) { |
|
5492 if (!isFunction(func)) { |
|
5493 throw new TypeError; |
|
5494 } |
|
5495 var args = slice(arguments, 1); |
|
5496 return setTimeout(function() { func.apply(undefined, args); }, 1); |
|
5497 } |
|
5498 |
|
5499 /** |
|
5500 * Executes the `func` function after `wait` milliseconds. Additional arguments |
|
5501 * will be provided to `func` when it is invoked. |
|
5502 * |
|
5503 * @static |
|
5504 * @memberOf _ |
|
5505 * @category Functions |
|
5506 * @param {Function} func The function to delay. |
|
5507 * @param {number} wait The number of milliseconds to delay execution. |
|
5508 * @param {...*} [arg] Arguments to invoke the function with. |
|
5509 * @returns {number} Returns the timer id. |
|
5510 * @example |
|
5511 * |
|
5512 * _.delay(function(text) { console.log(text); }, 1000, 'later'); |
|
5513 * // => logs 'later' after one second |
|
5514 */ |
|
5515 function delay(func, wait) { |
|
5516 if (!isFunction(func)) { |
|
5517 throw new TypeError; |
|
5518 } |
|
5519 var args = slice(arguments, 2); |
|
5520 return setTimeout(function() { func.apply(undefined, args); }, wait); |
|
5521 } |
|
5522 |
|
5523 /** |
|
5524 * Creates a function that memoizes the result of `func`. If `resolver` is |
|
5525 * provided it will be used to determine the cache key for storing the result |
|
5526 * based on the arguments provided to the memoized function. By default, the |
|
5527 * first argument provided to the memoized function is used as the cache key. |
|
5528 * The `func` is executed with the `this` binding of the memoized function. |
|
5529 * The result cache is exposed as the `cache` property on the memoized function. |
|
5530 * |
|
5531 * @static |
|
5532 * @memberOf _ |
|
5533 * @category Functions |
|
5534 * @param {Function} func The function to have its output memoized. |
|
5535 * @param {Function} [resolver] A function used to resolve the cache key. |
|
5536 * @returns {Function} Returns the new memoizing function. |
|
5537 * @example |
|
5538 * |
|
5539 * var fibonacci = _.memoize(function(n) { |
|
5540 * return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2); |
|
5541 * }); |
|
5542 * |
|
5543 * fibonacci(9) |
|
5544 * // => 34 |
|
5545 * |
|
5546 * var data = { |
|
5547 * 'fred': { 'name': 'fred', 'age': 40 }, |
|
5548 * 'pebbles': { 'name': 'pebbles', 'age': 1 } |
|
5549 * }; |
|
5550 * |
|
5551 * // modifying the result cache |
|
5552 * var get = _.memoize(function(name) { return data[name]; }, _.identity); |
|
5553 * get('pebbles'); |
|
5554 * // => { 'name': 'pebbles', 'age': 1 } |
|
5555 * |
|
5556 * get.cache.pebbles.name = 'penelope'; |
|
5557 * get('pebbles'); |
|
5558 * // => { 'name': 'penelope', 'age': 1 } |
|
5559 */ |
|
5560 function memoize(func, resolver) { |
|
5561 if (!isFunction(func)) { |
|
5562 throw new TypeError; |
|
5563 } |
|
5564 var memoized = function() { |
|
5565 var cache = memoized.cache, |
|
5566 key = resolver ? resolver.apply(this, arguments) : keyPrefix + arguments[0]; |
|
5567 |
|
5568 return hasOwnProperty.call(cache, key) |
|
5569 ? cache[key] |
|
5570 : (cache[key] = func.apply(this, arguments)); |
|
5571 } |
|
5572 memoized.cache = {}; |
|
5573 return memoized; |
7918 return memoized; |
5574 } |
7919 } |
5575 |
7920 |
5576 /** |
7921 /** |
5577 * Creates a function that is restricted to execute `func` once. Repeat calls to |
7922 * Creates a function that runs each argument through a corresponding |
5578 * the function will return the value of the first call. The `func` is executed |
7923 * transform function. |
5579 * with the `this` binding of the created function. |
7924 * |
5580 * |
7925 * @static |
5581 * @static |
7926 * @memberOf _ |
5582 * @memberOf _ |
7927 * @category Function |
5583 * @category Functions |
7928 * @param {Function} func The function to wrap. |
|
7929 * @param {...(Function|Function[])} [transforms] The functions to transform |
|
7930 * arguments, specified as individual functions or arrays of functions. |
|
7931 * @returns {Function} Returns the new function. |
|
7932 * @example |
|
7933 * |
|
7934 * function doubled(n) { |
|
7935 * return n * 2; |
|
7936 * } |
|
7937 * |
|
7938 * function square(n) { |
|
7939 * return n * n; |
|
7940 * } |
|
7941 * |
|
7942 * var modded = _.modArgs(function(x, y) { |
|
7943 * return [x, y]; |
|
7944 * }, square, doubled); |
|
7945 * |
|
7946 * modded(1, 2); |
|
7947 * // => [1, 4] |
|
7948 * |
|
7949 * modded(5, 10); |
|
7950 * // => [25, 20] |
|
7951 */ |
|
7952 var modArgs = restParam(function(func, transforms) { |
|
7953 transforms = baseFlatten(transforms); |
|
7954 if (typeof func != 'function' || !arrayEvery(transforms, baseIsFunction)) { |
|
7955 throw new TypeError(FUNC_ERROR_TEXT); |
|
7956 } |
|
7957 var length = transforms.length; |
|
7958 return restParam(function(args) { |
|
7959 var index = nativeMin(args.length, length); |
|
7960 while (index--) { |
|
7961 args[index] = transforms[index](args[index]); |
|
7962 } |
|
7963 return func.apply(this, args); |
|
7964 }); |
|
7965 }); |
|
7966 |
|
7967 /** |
|
7968 * Creates a function that negates the result of the predicate `func`. The |
|
7969 * `func` predicate is invoked with the `this` binding and arguments of the |
|
7970 * created function. |
|
7971 * |
|
7972 * @static |
|
7973 * @memberOf _ |
|
7974 * @category Function |
|
7975 * @param {Function} predicate The predicate to negate. |
|
7976 * @returns {Function} Returns the new function. |
|
7977 * @example |
|
7978 * |
|
7979 * function isEven(n) { |
|
7980 * return n % 2 == 0; |
|
7981 * } |
|
7982 * |
|
7983 * _.filter([1, 2, 3, 4, 5, 6], _.negate(isEven)); |
|
7984 * // => [1, 3, 5] |
|
7985 */ |
|
7986 function negate(predicate) { |
|
7987 if (typeof predicate != 'function') { |
|
7988 throw new TypeError(FUNC_ERROR_TEXT); |
|
7989 } |
|
7990 return function() { |
|
7991 return !predicate.apply(this, arguments); |
|
7992 }; |
|
7993 } |
|
7994 |
|
7995 /** |
|
7996 * Creates a function that is restricted to invoking `func` once. Repeat calls |
|
7997 * to the function return the value of the first call. The `func` is invoked |
|
7998 * with the `this` binding and arguments of the created function. |
|
7999 * |
|
8000 * @static |
|
8001 * @memberOf _ |
|
8002 * @category Function |
5584 * @param {Function} func The function to restrict. |
8003 * @param {Function} func The function to restrict. |
5585 * @returns {Function} Returns the new restricted function. |
8004 * @returns {Function} Returns the new restricted function. |
5586 * @example |
8005 * @example |
5587 * |
8006 * |
5588 * var initialize = _.once(createApplication); |
8007 * var initialize = _.once(createApplication); |
5589 * initialize(); |
8008 * initialize(); |
5590 * initialize(); |
8009 * initialize(); |
5591 * // `initialize` executes `createApplication` once |
8010 * // `initialize` invokes `createApplication` once |
5592 */ |
8011 */ |
5593 function once(func) { |
8012 function once(func) { |
5594 var ran, |
8013 return before(2, func); |
5595 result; |
8014 } |
5596 |
8015 |
5597 if (!isFunction(func)) { |
8016 /** |
5598 throw new TypeError; |
8017 * Creates a function that invokes `func` with `partial` arguments prepended |
5599 } |
8018 * to those provided to the new function. This method is like `_.bind` except |
|
8019 * it does **not** alter the `this` binding. |
|
8020 * |
|
8021 * The `_.partial.placeholder` value, which defaults to `_` in monolithic |
|
8022 * builds, may be used as a placeholder for partially applied arguments. |
|
8023 * |
|
8024 * **Note:** This method does not set the "length" property of partially |
|
8025 * applied functions. |
|
8026 * |
|
8027 * @static |
|
8028 * @memberOf _ |
|
8029 * @category Function |
|
8030 * @param {Function} func The function to partially apply arguments to. |
|
8031 * @param {...*} [partials] The arguments to be partially applied. |
|
8032 * @returns {Function} Returns the new partially applied function. |
|
8033 * @example |
|
8034 * |
|
8035 * var greet = function(greeting, name) { |
|
8036 * return greeting + ' ' + name; |
|
8037 * }; |
|
8038 * |
|
8039 * var sayHelloTo = _.partial(greet, 'hello'); |
|
8040 * sayHelloTo('fred'); |
|
8041 * // => 'hello fred' |
|
8042 * |
|
8043 * // using placeholders |
|
8044 * var greetFred = _.partial(greet, _, 'fred'); |
|
8045 * greetFred('hi'); |
|
8046 * // => 'hi fred' |
|
8047 */ |
|
8048 var partial = createPartial(PARTIAL_FLAG); |
|
8049 |
|
8050 /** |
|
8051 * This method is like `_.partial` except that partially applied arguments |
|
8052 * are appended to those provided to the new function. |
|
8053 * |
|
8054 * The `_.partialRight.placeholder` value, which defaults to `_` in monolithic |
|
8055 * builds, may be used as a placeholder for partially applied arguments. |
|
8056 * |
|
8057 * **Note:** This method does not set the "length" property of partially |
|
8058 * applied functions. |
|
8059 * |
|
8060 * @static |
|
8061 * @memberOf _ |
|
8062 * @category Function |
|
8063 * @param {Function} func The function to partially apply arguments to. |
|
8064 * @param {...*} [partials] The arguments to be partially applied. |
|
8065 * @returns {Function} Returns the new partially applied function. |
|
8066 * @example |
|
8067 * |
|
8068 * var greet = function(greeting, name) { |
|
8069 * return greeting + ' ' + name; |
|
8070 * }; |
|
8071 * |
|
8072 * var greetFred = _.partialRight(greet, 'fred'); |
|
8073 * greetFred('hi'); |
|
8074 * // => 'hi fred' |
|
8075 * |
|
8076 * // using placeholders |
|
8077 * var sayHelloTo = _.partialRight(greet, 'hello', _); |
|
8078 * sayHelloTo('fred'); |
|
8079 * // => 'hello fred' |
|
8080 */ |
|
8081 var partialRight = createPartial(PARTIAL_RIGHT_FLAG); |
|
8082 |
|
8083 /** |
|
8084 * Creates a function that invokes `func` with arguments arranged according |
|
8085 * to the specified indexes where the argument value at the first index is |
|
8086 * provided as the first argument, the argument value at the second index is |
|
8087 * provided as the second argument, and so on. |
|
8088 * |
|
8089 * @static |
|
8090 * @memberOf _ |
|
8091 * @category Function |
|
8092 * @param {Function} func The function to rearrange arguments for. |
|
8093 * @param {...(number|number[])} indexes The arranged argument indexes, |
|
8094 * specified as individual indexes or arrays of indexes. |
|
8095 * @returns {Function} Returns the new function. |
|
8096 * @example |
|
8097 * |
|
8098 * var rearged = _.rearg(function(a, b, c) { |
|
8099 * return [a, b, c]; |
|
8100 * }, 2, 0, 1); |
|
8101 * |
|
8102 * rearged('b', 'c', 'a') |
|
8103 * // => ['a', 'b', 'c'] |
|
8104 * |
|
8105 * var map = _.rearg(_.map, [1, 0]); |
|
8106 * map(function(n) { |
|
8107 * return n * 3; |
|
8108 * }, [1, 2, 3]); |
|
8109 * // => [3, 6, 9] |
|
8110 */ |
|
8111 var rearg = restParam(function(func, indexes) { |
|
8112 return createWrapper(func, REARG_FLAG, undefined, undefined, undefined, baseFlatten(indexes)); |
|
8113 }); |
|
8114 |
|
8115 /** |
|
8116 * Creates a function that invokes `func` with the `this` binding of the |
|
8117 * created function and arguments from `start` and beyond provided as an array. |
|
8118 * |
|
8119 * **Note:** This method is based on the [rest parameter](https://developer.mozilla.org/Web/JavaScript/Reference/Functions/rest_parameters). |
|
8120 * |
|
8121 * @static |
|
8122 * @memberOf _ |
|
8123 * @category Function |
|
8124 * @param {Function} func The function to apply a rest parameter to. |
|
8125 * @param {number} [start=func.length-1] The start position of the rest parameter. |
|
8126 * @returns {Function} Returns the new function. |
|
8127 * @example |
|
8128 * |
|
8129 * var say = _.restParam(function(what, names) { |
|
8130 * return what + ' ' + _.initial(names).join(', ') + |
|
8131 * (_.size(names) > 1 ? ', & ' : '') + _.last(names); |
|
8132 * }); |
|
8133 * |
|
8134 * say('hello', 'fred', 'barney', 'pebbles'); |
|
8135 * // => 'hello fred, barney, & pebbles' |
|
8136 */ |
|
8137 function restParam(func, start) { |
|
8138 if (typeof func != 'function') { |
|
8139 throw new TypeError(FUNC_ERROR_TEXT); |
|
8140 } |
|
8141 start = nativeMax(start === undefined ? (func.length - 1) : (+start || 0), 0); |
5600 return function() { |
8142 return function() { |
5601 if (ran) { |
8143 var args = arguments, |
5602 return result; |
8144 index = -1, |
5603 } |
8145 length = nativeMax(args.length - start, 0), |
5604 ran = true; |
8146 rest = Array(length); |
5605 result = func.apply(this, arguments); |
8147 |
5606 |
8148 while (++index < length) { |
5607 // clear the `func` variable so the function may be garbage collected |
8149 rest[index] = args[start + index]; |
5608 func = null; |
8150 } |
5609 return result; |
8151 switch (start) { |
|
8152 case 0: return func.call(this, rest); |
|
8153 case 1: return func.call(this, args[0], rest); |
|
8154 case 2: return func.call(this, args[0], args[1], rest); |
|
8155 } |
|
8156 var otherArgs = Array(start + 1); |
|
8157 index = -1; |
|
8158 while (++index < start) { |
|
8159 otherArgs[index] = args[index]; |
|
8160 } |
|
8161 otherArgs[start] = rest; |
|
8162 return func.apply(this, otherArgs); |
5610 }; |
8163 }; |
5611 } |
8164 } |
5612 |
8165 |
5613 /** |
8166 /** |
5614 * Creates a function that, when called, invokes `func` with any additional |
8167 * Creates a function that invokes `func` with the `this` binding of the created |
5615 * `partial` arguments prepended to those provided to the new function. This |
8168 * function and an array of arguments much like [`Function#apply`](https://es5.github.io/#x15.3.4.3). |
5616 * method is similar to `_.bind` except it does **not** alter the `this` binding. |
8169 * |
5617 * |
8170 * **Note:** This method is based on the [spread operator](https://developer.mozilla.org/Web/JavaScript/Reference/Operators/Spread_operator). |
5618 * @static |
8171 * |
5619 * @memberOf _ |
8172 * @static |
5620 * @category Functions |
8173 * @memberOf _ |
5621 * @param {Function} func The function to partially apply arguments to. |
8174 * @category Function |
5622 * @param {...*} [arg] Arguments to be partially applied. |
8175 * @param {Function} func The function to spread arguments over. |
5623 * @returns {Function} Returns the new partially applied function. |
8176 * @returns {Function} Returns the new function. |
5624 * @example |
8177 * @example |
5625 * |
8178 * |
5626 * var greet = function(greeting, name) { return greeting + ' ' + name; }; |
8179 * var say = _.spread(function(who, what) { |
5627 * var hi = _.partial(greet, 'hi'); |
8180 * return who + ' says ' + what; |
5628 * hi('fred'); |
8181 * }); |
5629 * // => 'hi fred' |
8182 * |
5630 */ |
8183 * say(['fred', 'hello']); |
5631 function partial(func) { |
8184 * // => 'fred says hello' |
5632 return createWrapper(func, 16, slice(arguments, 1)); |
8185 * |
5633 } |
8186 * // with a Promise |
5634 |
8187 * var numbers = Promise.all([ |
5635 /** |
8188 * Promise.resolve(40), |
5636 * This method is like `_.partial` except that `partial` arguments are |
8189 * Promise.resolve(36) |
5637 * appended to those provided to the new function. |
8190 * ]); |
5638 * |
8191 * |
5639 * @static |
8192 * numbers.then(_.spread(function(x, y) { |
5640 * @memberOf _ |
8193 * return x + y; |
5641 * @category Functions |
8194 * })); |
5642 * @param {Function} func The function to partially apply arguments to. |
8195 * // => a Promise of 76 |
5643 * @param {...*} [arg] Arguments to be partially applied. |
8196 */ |
5644 * @returns {Function} Returns the new partially applied function. |
8197 function spread(func) { |
5645 * @example |
8198 if (typeof func != 'function') { |
5646 * |
8199 throw new TypeError(FUNC_ERROR_TEXT); |
5647 * var defaultsDeep = _.partialRight(_.merge, _.defaults); |
8200 } |
5648 * |
8201 return function(array) { |
5649 * var options = { |
8202 return func.apply(this, array); |
5650 * 'variable': 'data', |
8203 }; |
5651 * 'imports': { 'jq': $ } |
8204 } |
5652 * }; |
8205 |
5653 * |
8206 /** |
5654 * defaultsDeep(options, _.templateSettings); |
8207 * Creates a throttled function that only invokes `func` at most once per |
5655 * |
8208 * every `wait` milliseconds. The throttled function comes with a `cancel` |
5656 * options.variable |
8209 * method to cancel delayed invocations. Provide an options object to indicate |
5657 * // => 'data' |
8210 * that `func` should be invoked on the leading and/or trailing edge of the |
5658 * |
8211 * `wait` timeout. Subsequent calls to the throttled function return the |
5659 * options.imports |
8212 * result of the last `func` call. |
5660 * // => { '_': _, 'jq': $ } |
8213 * |
5661 */ |
8214 * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked |
5662 function partialRight(func) { |
|
5663 return createWrapper(func, 32, null, slice(arguments, 1)); |
|
5664 } |
|
5665 |
|
5666 /** |
|
5667 * Creates a function that, when executed, will only call the `func` function |
|
5668 * at most once per every `wait` milliseconds. Provide an options object to |
|
5669 * indicate that `func` should be invoked on the leading and/or trailing edge |
|
5670 * of the `wait` timeout. Subsequent calls to the throttled function will |
|
5671 * return the result of the last `func` call. |
|
5672 * |
|
5673 * Note: If `leading` and `trailing` options are `true` `func` will be called |
|
5674 * on the trailing edge of the timeout only if the the throttled function is |
8215 * on the trailing edge of the timeout only if the the throttled function is |
5675 * invoked more than once during the `wait` timeout. |
8216 * invoked more than once during the `wait` timeout. |
5676 * |
8217 * |
5677 * @static |
8218 * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation) |
5678 * @memberOf _ |
8219 * for details over the differences between `_.throttle` and `_.debounce`. |
5679 * @category Functions |
8220 * |
|
8221 * @static |
|
8222 * @memberOf _ |
|
8223 * @category Function |
5680 * @param {Function} func The function to throttle. |
8224 * @param {Function} func The function to throttle. |
5681 * @param {number} wait The number of milliseconds to throttle executions to. |
8225 * @param {number} [wait=0] The number of milliseconds to throttle invocations to. |
5682 * @param {Object} [options] The options object. |
8226 * @param {Object} [options] The options object. |
5683 * @param {boolean} [options.leading=true] Specify execution on the leading edge of the timeout. |
8227 * @param {boolean} [options.leading=true] Specify invoking on the leading |
5684 * @param {boolean} [options.trailing=true] Specify execution on the trailing edge of the timeout. |
8228 * edge of the timeout. |
|
8229 * @param {boolean} [options.trailing=true] Specify invoking on the trailing |
|
8230 * edge of the timeout. |
5685 * @returns {Function} Returns the new throttled function. |
8231 * @returns {Function} Returns the new throttled function. |
5686 * @example |
8232 * @example |
5687 * |
8233 * |
5688 * // avoid excessively updating the position while scrolling |
8234 * // avoid excessively updating the position while scrolling |
5689 * var throttled = _.throttle(updatePosition, 100); |
8235 * jQuery(window).on('scroll', _.throttle(updatePosition, 100)); |
5690 * jQuery(window).on('scroll', throttled); |
8236 * |
5691 * |
8237 * // invoke `renewToken` when the click event is fired, but not more than once every 5 minutes |
5692 * // execute `renewToken` when the click event is fired, but not more than once every 5 minutes |
|
5693 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { |
8238 * jQuery('.interactive').on('click', _.throttle(renewToken, 300000, { |
5694 * 'trailing': false |
8239 * 'trailing': false |
5695 * })); |
8240 * })); |
|
8241 * |
|
8242 * // cancel a trailing throttled call |
|
8243 * jQuery(window).on('popstate', throttled.cancel); |
5696 */ |
8244 */ |
5697 function throttle(func, wait, options) { |
8245 function throttle(func, wait, options) { |
5698 var leading = true, |
8246 var leading = true, |
5699 trailing = true; |
8247 trailing = true; |
5700 |
8248 |
5701 if (!isFunction(func)) { |
8249 if (typeof func != 'function') { |
5702 throw new TypeError; |
8250 throw new TypeError(FUNC_ERROR_TEXT); |
5703 } |
8251 } |
5704 if (options === false) { |
8252 if (options === false) { |
5705 leading = false; |
8253 leading = false; |
5706 } else if (isObject(options)) { |
8254 } else if (isObject(options)) { |
5707 leading = 'leading' in options ? options.leading : leading; |
8255 leading = 'leading' in options ? !!options.leading : leading; |
5708 trailing = 'trailing' in options ? options.trailing : trailing; |
8256 trailing = 'trailing' in options ? !!options.trailing : trailing; |
5709 } |
8257 } |
5710 debounceOptions.leading = leading; |
8258 return debounce(func, wait, { 'leading': leading, 'maxWait': +wait, 'trailing': trailing }); |
5711 debounceOptions.maxWait = wait; |
|
5712 debounceOptions.trailing = trailing; |
|
5713 |
|
5714 return debounce(func, wait, debounceOptions); |
|
5715 } |
8259 } |
5716 |
8260 |
5717 /** |
8261 /** |
5718 * Creates a function that provides `value` to the wrapper function as its |
8262 * Creates a function that provides `value` to the wrapper function as its |
5719 * first argument. Additional arguments provided to the function are appended |
8263 * first argument. Any additional arguments provided to the function are |
5720 * to those provided to the wrapper function. The wrapper is executed with |
8264 * appended to those provided to the wrapper function. The wrapper is invoked |
5721 * the `this` binding of the created function. |
8265 * with the `this` binding of the created function. |
5722 * |
8266 * |
5723 * @static |
8267 * @static |
5724 * @memberOf _ |
8268 * @memberOf _ |
5725 * @category Functions |
8269 * @category Function |
5726 * @param {*} value The value to wrap. |
8270 * @param {*} value The value to wrap. |
5727 * @param {Function} wrapper The wrapper function. |
8271 * @param {Function} wrapper The wrapper function. |
5728 * @returns {Function} Returns the new function. |
8272 * @returns {Function} Returns the new function. |
5729 * @example |
8273 * @example |
5730 * |
8274 * |
5731 * var p = _.wrap(_.escape, function(func, text) { |
8275 * var p = _.wrap(_.escape, function(func, text) { |
5732 * return '<p>' + func(text) + '</p>'; |
8276 * return '<p>' + func(text) + '</p>'; |
5733 * }); |
8277 * }); |
5734 * |
8278 * |
5735 * p('Fred, Wilma, & Pebbles'); |
8279 * p('fred, barney, & pebbles'); |
5736 * // => '<p>Fred, Wilma, & Pebbles</p>' |
8280 * // => '<p>fred, barney, & pebbles</p>' |
5737 */ |
8281 */ |
5738 function wrap(value, wrapper) { |
8282 function wrap(value, wrapper) { |
5739 return createWrapper(wrapper, 16, [value]); |
8283 wrapper = wrapper == null ? identity : wrapper; |
5740 } |
8284 return createWrapper(wrapper, PARTIAL_FLAG, undefined, [value], []); |
5741 |
8285 } |
5742 /*--------------------------------------------------------------------------*/ |
8286 |
5743 |
8287 /*------------------------------------------------------------------------*/ |
5744 /** |
8288 |
5745 * Creates a function that returns `value`. |
8289 /** |
5746 * |
8290 * Creates a clone of `value`. If `isDeep` is `true` nested objects are cloned, |
5747 * @static |
8291 * otherwise they are assigned by reference. If `customizer` is provided it's |
5748 * @memberOf _ |
8292 * invoked to produce the cloned values. If `customizer` returns `undefined` |
5749 * @category Utilities |
8293 * cloning is handled by the method instead. The `customizer` is bound to |
5750 * @param {*} value The value to return from the new function. |
8294 * `thisArg` and invoked with up to three argument; (value [, index|key, object]). |
5751 * @returns {Function} Returns the new function. |
8295 * |
5752 * @example |
8296 * **Note:** This method is loosely based on the |
5753 * |
8297 * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
5754 * var object = { 'name': 'fred' }; |
8298 * The enumerable properties of `arguments` objects and objects created by |
5755 * var getter = _.constant(object); |
8299 * constructors other than `Object` are cloned to plain `Object` objects. An |
5756 * getter() === object; |
8300 * empty object is returned for uncloneable values such as functions, DOM nodes, |
|
8301 * Maps, Sets, and WeakMaps. |
|
8302 * |
|
8303 * @static |
|
8304 * @memberOf _ |
|
8305 * @category Lang |
|
8306 * @param {*} value The value to clone. |
|
8307 * @param {boolean} [isDeep] Specify a deep clone. |
|
8308 * @param {Function} [customizer] The function to customize cloning values. |
|
8309 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
8310 * @returns {*} Returns the cloned value. |
|
8311 * @example |
|
8312 * |
|
8313 * var users = [ |
|
8314 * { 'user': 'barney' }, |
|
8315 * { 'user': 'fred' } |
|
8316 * ]; |
|
8317 * |
|
8318 * var shallow = _.clone(users); |
|
8319 * shallow[0] === users[0]; |
5757 * // => true |
8320 * // => true |
5758 */ |
8321 * |
5759 function constant(value) { |
8322 * var deep = _.clone(users, true); |
5760 return function() { |
8323 * deep[0] === users[0]; |
5761 return value; |
8324 * // => false |
5762 }; |
8325 * |
5763 } |
8326 * // using a customizer callback |
5764 |
8327 * var el = _.clone(document.body, function(value) { |
5765 /** |
8328 * if (_.isElement(value)) { |
5766 * Produces a callback bound to an optional `thisArg`. If `func` is a property |
8329 * return value.cloneNode(false); |
5767 * name the created callback will return the property value for a given element. |
8330 * } |
5768 * If `func` is an object the created callback will return `true` for elements |
8331 * }); |
5769 * that contain the equivalent object properties, otherwise it will return `false`. |
8332 * |
5770 * |
8333 * el === document.body |
5771 * @static |
8334 * // => false |
5772 * @memberOf _ |
8335 * el.nodeName |
5773 * @category Utilities |
8336 * // => BODY |
5774 * @param {*} [func=identity] The value to convert to a callback. |
8337 * el.childNodes.length; |
5775 * @param {*} [thisArg] The `this` binding of the created callback. |
8338 * // => 0 |
5776 * @param {number} [argCount] The number of arguments the callback accepts. |
8339 */ |
5777 * @returns {Function} Returns a callback function. |
8340 function clone(value, isDeep, customizer, thisArg) { |
5778 * @example |
8341 if (isDeep && typeof isDeep != 'boolean' && isIterateeCall(value, isDeep, customizer)) { |
5779 * |
8342 isDeep = false; |
5780 * var characters = [ |
8343 } |
5781 * { 'name': 'barney', 'age': 36 }, |
8344 else if (typeof isDeep == 'function') { |
5782 * { 'name': 'fred', 'age': 40 } |
8345 thisArg = customizer; |
|
8346 customizer = isDeep; |
|
8347 isDeep = false; |
|
8348 } |
|
8349 return typeof customizer == 'function' |
|
8350 ? baseClone(value, isDeep, bindCallback(customizer, thisArg, 3)) |
|
8351 : baseClone(value, isDeep); |
|
8352 } |
|
8353 |
|
8354 /** |
|
8355 * Creates a deep clone of `value`. If `customizer` is provided it's invoked |
|
8356 * to produce the cloned values. If `customizer` returns `undefined` cloning |
|
8357 * is handled by the method instead. The `customizer` is bound to `thisArg` |
|
8358 * and invoked with up to three argument; (value [, index|key, object]). |
|
8359 * |
|
8360 * **Note:** This method is loosely based on the |
|
8361 * [structured clone algorithm](http://www.w3.org/TR/html5/infrastructure.html#internal-structured-cloning-algorithm). |
|
8362 * The enumerable properties of `arguments` objects and objects created by |
|
8363 * constructors other than `Object` are cloned to plain `Object` objects. An |
|
8364 * empty object is returned for uncloneable values such as functions, DOM nodes, |
|
8365 * Maps, Sets, and WeakMaps. |
|
8366 * |
|
8367 * @static |
|
8368 * @memberOf _ |
|
8369 * @category Lang |
|
8370 * @param {*} value The value to deep clone. |
|
8371 * @param {Function} [customizer] The function to customize cloning values. |
|
8372 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
8373 * @returns {*} Returns the deep cloned value. |
|
8374 * @example |
|
8375 * |
|
8376 * var users = [ |
|
8377 * { 'user': 'barney' }, |
|
8378 * { 'user': 'fred' } |
5783 * ]; |
8379 * ]; |
5784 * |
8380 * |
5785 * // wrap to create custom callback shorthands |
8381 * var deep = _.cloneDeep(users); |
5786 * _.createCallback = _.wrap(_.createCallback, function(func, callback, thisArg) { |
8382 * deep[0] === users[0]; |
5787 * var match = /^(.+?)__([gl]t)(.+)$/.exec(callback); |
8383 * // => false |
5788 * return !match ? func(callback, thisArg) : function(object) { |
8384 * |
5789 * return match[2] == 'gt' ? object[match[1]] > match[3] : object[match[1]] < match[3]; |
8385 * // using a customizer callback |
5790 * }; |
8386 * var el = _.cloneDeep(document.body, function(value) { |
|
8387 * if (_.isElement(value)) { |
|
8388 * return value.cloneNode(true); |
|
8389 * } |
5791 * }); |
8390 * }); |
5792 * |
8391 * |
5793 * _.filter(characters, 'age__gt38'); |
8392 * el === document.body |
5794 * // => [{ 'name': 'fred', 'age': 40 }] |
8393 * // => false |
5795 */ |
8394 * el.nodeName |
5796 function createCallback(func, thisArg, argCount) { |
8395 * // => BODY |
5797 var type = typeof func; |
8396 * el.childNodes.length; |
5798 if (func == null || type == 'function') { |
8397 * // => 20 |
5799 return baseCreateCallback(func, thisArg, argCount); |
8398 */ |
5800 } |
8399 function cloneDeep(value, customizer, thisArg) { |
5801 // handle "_.pluck" style callback shorthands |
8400 return typeof customizer == 'function' |
5802 if (type != 'object') { |
8401 ? baseClone(value, true, bindCallback(customizer, thisArg, 3)) |
5803 return property(func); |
8402 : baseClone(value, true); |
5804 } |
8403 } |
5805 var props = keys(func), |
8404 |
5806 key = props[0], |
8405 /** |
5807 a = func[key]; |
8406 * Checks if `value` is greater than `other`. |
5808 |
8407 * |
5809 // handle "_.where" style callback shorthands |
8408 * @static |
5810 if (props.length == 1 && a === a && !isObject(a)) { |
8409 * @memberOf _ |
5811 // fast path the common case of providing an object with a single |
8410 * @category Lang |
5812 // property containing a primitive value |
8411 * @param {*} value The value to compare. |
5813 return function(object) { |
8412 * @param {*} other The other value to compare. |
5814 var b = object[key]; |
8413 * @returns {boolean} Returns `true` if `value` is greater than `other`, else `false`. |
5815 return a === b && (a !== 0 || (1 / a == 1 / b)); |
8414 * @example |
5816 }; |
8415 * |
5817 } |
8416 * _.gt(3, 1); |
5818 return function(object) { |
8417 * // => true |
5819 var length = props.length, |
8418 * |
5820 result = false; |
8419 * _.gt(3, 3); |
5821 |
8420 * // => false |
5822 while (length--) { |
8421 * |
5823 if (!(result = baseIsEqual(object[props[length]], func[props[length]], null, true))) { |
8422 * _.gt(1, 3); |
5824 break; |
8423 * // => false |
|
8424 */ |
|
8425 function gt(value, other) { |
|
8426 return value > other; |
|
8427 } |
|
8428 |
|
8429 /** |
|
8430 * Checks if `value` is greater than or equal to `other`. |
|
8431 * |
|
8432 * @static |
|
8433 * @memberOf _ |
|
8434 * @category Lang |
|
8435 * @param {*} value The value to compare. |
|
8436 * @param {*} other The other value to compare. |
|
8437 * @returns {boolean} Returns `true` if `value` is greater than or equal to `other`, else `false`. |
|
8438 * @example |
|
8439 * |
|
8440 * _.gte(3, 1); |
|
8441 * // => true |
|
8442 * |
|
8443 * _.gte(3, 3); |
|
8444 * // => true |
|
8445 * |
|
8446 * _.gte(1, 3); |
|
8447 * // => false |
|
8448 */ |
|
8449 function gte(value, other) { |
|
8450 return value >= other; |
|
8451 } |
|
8452 |
|
8453 /** |
|
8454 * Checks if `value` is classified as an `arguments` object. |
|
8455 * |
|
8456 * @static |
|
8457 * @memberOf _ |
|
8458 * @category Lang |
|
8459 * @param {*} value The value to check. |
|
8460 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8461 * @example |
|
8462 * |
|
8463 * _.isArguments(function() { return arguments; }()); |
|
8464 * // => true |
|
8465 * |
|
8466 * _.isArguments([1, 2, 3]); |
|
8467 * // => false |
|
8468 */ |
|
8469 function isArguments(value) { |
|
8470 return isObjectLike(value) && isArrayLike(value) && |
|
8471 hasOwnProperty.call(value, 'callee') && !propertyIsEnumerable.call(value, 'callee'); |
|
8472 } |
|
8473 |
|
8474 /** |
|
8475 * Checks if `value` is classified as an `Array` object. |
|
8476 * |
|
8477 * @static |
|
8478 * @memberOf _ |
|
8479 * @category Lang |
|
8480 * @param {*} value The value to check. |
|
8481 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8482 * @example |
|
8483 * |
|
8484 * _.isArray([1, 2, 3]); |
|
8485 * // => true |
|
8486 * |
|
8487 * _.isArray(function() { return arguments; }()); |
|
8488 * // => false |
|
8489 */ |
|
8490 var isArray = nativeIsArray || function(value) { |
|
8491 return isObjectLike(value) && isLength(value.length) && objToString.call(value) == arrayTag; |
|
8492 }; |
|
8493 |
|
8494 /** |
|
8495 * Checks if `value` is classified as a boolean primitive or object. |
|
8496 * |
|
8497 * @static |
|
8498 * @memberOf _ |
|
8499 * @category Lang |
|
8500 * @param {*} value The value to check. |
|
8501 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8502 * @example |
|
8503 * |
|
8504 * _.isBoolean(false); |
|
8505 * // => true |
|
8506 * |
|
8507 * _.isBoolean(null); |
|
8508 * // => false |
|
8509 */ |
|
8510 function isBoolean(value) { |
|
8511 return value === true || value === false || (isObjectLike(value) && objToString.call(value) == boolTag); |
|
8512 } |
|
8513 |
|
8514 /** |
|
8515 * Checks if `value` is classified as a `Date` object. |
|
8516 * |
|
8517 * @static |
|
8518 * @memberOf _ |
|
8519 * @category Lang |
|
8520 * @param {*} value The value to check. |
|
8521 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8522 * @example |
|
8523 * |
|
8524 * _.isDate(new Date); |
|
8525 * // => true |
|
8526 * |
|
8527 * _.isDate('Mon April 23 2012'); |
|
8528 * // => false |
|
8529 */ |
|
8530 function isDate(value) { |
|
8531 return isObjectLike(value) && objToString.call(value) == dateTag; |
|
8532 } |
|
8533 |
|
8534 /** |
|
8535 * Checks if `value` is a DOM element. |
|
8536 * |
|
8537 * @static |
|
8538 * @memberOf _ |
|
8539 * @category Lang |
|
8540 * @param {*} value The value to check. |
|
8541 * @returns {boolean} Returns `true` if `value` is a DOM element, else `false`. |
|
8542 * @example |
|
8543 * |
|
8544 * _.isElement(document.body); |
|
8545 * // => true |
|
8546 * |
|
8547 * _.isElement('<body>'); |
|
8548 * // => false |
|
8549 */ |
|
8550 function isElement(value) { |
|
8551 return !!value && value.nodeType === 1 && isObjectLike(value) && !isPlainObject(value); |
|
8552 } |
|
8553 |
|
8554 /** |
|
8555 * Checks if `value` is empty. A value is considered empty unless it's an |
|
8556 * `arguments` object, array, string, or jQuery-like collection with a length |
|
8557 * greater than `0` or an object with own enumerable properties. |
|
8558 * |
|
8559 * @static |
|
8560 * @memberOf _ |
|
8561 * @category Lang |
|
8562 * @param {Array|Object|string} value The value to inspect. |
|
8563 * @returns {boolean} Returns `true` if `value` is empty, else `false`. |
|
8564 * @example |
|
8565 * |
|
8566 * _.isEmpty(null); |
|
8567 * // => true |
|
8568 * |
|
8569 * _.isEmpty(true); |
|
8570 * // => true |
|
8571 * |
|
8572 * _.isEmpty(1); |
|
8573 * // => true |
|
8574 * |
|
8575 * _.isEmpty([1, 2, 3]); |
|
8576 * // => false |
|
8577 * |
|
8578 * _.isEmpty({ 'a': 1 }); |
|
8579 * // => false |
|
8580 */ |
|
8581 function isEmpty(value) { |
|
8582 if (value == null) { |
|
8583 return true; |
|
8584 } |
|
8585 if (isArrayLike(value) && (isArray(value) || isString(value) || isArguments(value) || |
|
8586 (isObjectLike(value) && isFunction(value.splice)))) { |
|
8587 return !value.length; |
|
8588 } |
|
8589 return !keys(value).length; |
|
8590 } |
|
8591 |
|
8592 /** |
|
8593 * Performs a deep comparison between two values to determine if they are |
|
8594 * equivalent. If `customizer` is provided it's invoked to compare values. |
|
8595 * If `customizer` returns `undefined` comparisons are handled by the method |
|
8596 * instead. The `customizer` is bound to `thisArg` and invoked with up to |
|
8597 * three arguments: (value, other [, index|key]). |
|
8598 * |
|
8599 * **Note:** This method supports comparing arrays, booleans, `Date` objects, |
|
8600 * numbers, `Object` objects, regexes, and strings. Objects are compared by |
|
8601 * their own, not inherited, enumerable properties. Functions and DOM nodes |
|
8602 * are **not** supported. Provide a customizer function to extend support |
|
8603 * for comparing other values. |
|
8604 * |
|
8605 * @static |
|
8606 * @memberOf _ |
|
8607 * @alias eq |
|
8608 * @category Lang |
|
8609 * @param {*} value The value to compare. |
|
8610 * @param {*} other The other value to compare. |
|
8611 * @param {Function} [customizer] The function to customize value comparisons. |
|
8612 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
8613 * @returns {boolean} Returns `true` if the values are equivalent, else `false`. |
|
8614 * @example |
|
8615 * |
|
8616 * var object = { 'user': 'fred' }; |
|
8617 * var other = { 'user': 'fred' }; |
|
8618 * |
|
8619 * object == other; |
|
8620 * // => false |
|
8621 * |
|
8622 * _.isEqual(object, other); |
|
8623 * // => true |
|
8624 * |
|
8625 * // using a customizer callback |
|
8626 * var array = ['hello', 'goodbye']; |
|
8627 * var other = ['hi', 'goodbye']; |
|
8628 * |
|
8629 * _.isEqual(array, other, function(value, other) { |
|
8630 * if (_.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/)) { |
|
8631 * return true; |
|
8632 * } |
|
8633 * }); |
|
8634 * // => true |
|
8635 */ |
|
8636 function isEqual(value, other, customizer, thisArg) { |
|
8637 customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; |
|
8638 var result = customizer ? customizer(value, other) : undefined; |
|
8639 return result === undefined ? baseIsEqual(value, other, customizer) : !!result; |
|
8640 } |
|
8641 |
|
8642 /** |
|
8643 * Checks if `value` is an `Error`, `EvalError`, `RangeError`, `ReferenceError`, |
|
8644 * `SyntaxError`, `TypeError`, or `URIError` object. |
|
8645 * |
|
8646 * @static |
|
8647 * @memberOf _ |
|
8648 * @category Lang |
|
8649 * @param {*} value The value to check. |
|
8650 * @returns {boolean} Returns `true` if `value` is an error object, else `false`. |
|
8651 * @example |
|
8652 * |
|
8653 * _.isError(new Error); |
|
8654 * // => true |
|
8655 * |
|
8656 * _.isError(Error); |
|
8657 * // => false |
|
8658 */ |
|
8659 function isError(value) { |
|
8660 return isObjectLike(value) && typeof value.message == 'string' && objToString.call(value) == errorTag; |
|
8661 } |
|
8662 |
|
8663 /** |
|
8664 * Checks if `value` is a finite primitive number. |
|
8665 * |
|
8666 * **Note:** This method is based on [`Number.isFinite`](http://ecma-international.org/ecma-262/6.0/#sec-number.isfinite). |
|
8667 * |
|
8668 * @static |
|
8669 * @memberOf _ |
|
8670 * @category Lang |
|
8671 * @param {*} value The value to check. |
|
8672 * @returns {boolean} Returns `true` if `value` is a finite number, else `false`. |
|
8673 * @example |
|
8674 * |
|
8675 * _.isFinite(10); |
|
8676 * // => true |
|
8677 * |
|
8678 * _.isFinite('10'); |
|
8679 * // => false |
|
8680 * |
|
8681 * _.isFinite(true); |
|
8682 * // => false |
|
8683 * |
|
8684 * _.isFinite(Object(10)); |
|
8685 * // => false |
|
8686 * |
|
8687 * _.isFinite(Infinity); |
|
8688 * // => false |
|
8689 */ |
|
8690 function isFinite(value) { |
|
8691 return typeof value == 'number' && nativeIsFinite(value); |
|
8692 } |
|
8693 |
|
8694 /** |
|
8695 * Checks if `value` is classified as a `Function` object. |
|
8696 * |
|
8697 * @static |
|
8698 * @memberOf _ |
|
8699 * @category Lang |
|
8700 * @param {*} value The value to check. |
|
8701 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8702 * @example |
|
8703 * |
|
8704 * _.isFunction(_); |
|
8705 * // => true |
|
8706 * |
|
8707 * _.isFunction(/abc/); |
|
8708 * // => false |
|
8709 */ |
|
8710 function isFunction(value) { |
|
8711 // The use of `Object#toString` avoids issues with the `typeof` operator |
|
8712 // in older versions of Chrome and Safari which return 'function' for regexes |
|
8713 // and Safari 8 which returns 'object' for typed array constructors. |
|
8714 return isObject(value) && objToString.call(value) == funcTag; |
|
8715 } |
|
8716 |
|
8717 /** |
|
8718 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`. |
|
8719 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) |
|
8720 * |
|
8721 * @static |
|
8722 * @memberOf _ |
|
8723 * @category Lang |
|
8724 * @param {*} value The value to check. |
|
8725 * @returns {boolean} Returns `true` if `value` is an object, else `false`. |
|
8726 * @example |
|
8727 * |
|
8728 * _.isObject({}); |
|
8729 * // => true |
|
8730 * |
|
8731 * _.isObject([1, 2, 3]); |
|
8732 * // => true |
|
8733 * |
|
8734 * _.isObject(1); |
|
8735 * // => false |
|
8736 */ |
|
8737 function isObject(value) { |
|
8738 // Avoid a V8 JIT bug in Chrome 19-20. |
|
8739 // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. |
|
8740 var type = typeof value; |
|
8741 return !!value && (type == 'object' || type == 'function'); |
|
8742 } |
|
8743 |
|
8744 /** |
|
8745 * Performs a deep comparison between `object` and `source` to determine if |
|
8746 * `object` contains equivalent property values. If `customizer` is provided |
|
8747 * it's invoked to compare values. If `customizer` returns `undefined` |
|
8748 * comparisons are handled by the method instead. The `customizer` is bound |
|
8749 * to `thisArg` and invoked with three arguments: (value, other, index|key). |
|
8750 * |
|
8751 * **Note:** This method supports comparing properties of arrays, booleans, |
|
8752 * `Date` objects, numbers, `Object` objects, regexes, and strings. Functions |
|
8753 * and DOM nodes are **not** supported. Provide a customizer function to extend |
|
8754 * support for comparing other values. |
|
8755 * |
|
8756 * @static |
|
8757 * @memberOf _ |
|
8758 * @category Lang |
|
8759 * @param {Object} object The object to inspect. |
|
8760 * @param {Object} source The object of property values to match. |
|
8761 * @param {Function} [customizer] The function to customize value comparisons. |
|
8762 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
8763 * @returns {boolean} Returns `true` if `object` is a match, else `false`. |
|
8764 * @example |
|
8765 * |
|
8766 * var object = { 'user': 'fred', 'age': 40 }; |
|
8767 * |
|
8768 * _.isMatch(object, { 'age': 40 }); |
|
8769 * // => true |
|
8770 * |
|
8771 * _.isMatch(object, { 'age': 36 }); |
|
8772 * // => false |
|
8773 * |
|
8774 * // using a customizer callback |
|
8775 * var object = { 'greeting': 'hello' }; |
|
8776 * var source = { 'greeting': 'hi' }; |
|
8777 * |
|
8778 * _.isMatch(object, source, function(value, other) { |
|
8779 * return _.every([value, other], RegExp.prototype.test, /^h(?:i|ello)$/) || undefined; |
|
8780 * }); |
|
8781 * // => true |
|
8782 */ |
|
8783 function isMatch(object, source, customizer, thisArg) { |
|
8784 customizer = typeof customizer == 'function' ? bindCallback(customizer, thisArg, 3) : undefined; |
|
8785 return baseIsMatch(object, getMatchData(source), customizer); |
|
8786 } |
|
8787 |
|
8788 /** |
|
8789 * Checks if `value` is `NaN`. |
|
8790 * |
|
8791 * **Note:** This method is not the same as [`isNaN`](https://es5.github.io/#x15.1.2.4) |
|
8792 * which returns `true` for `undefined` and other non-numeric values. |
|
8793 * |
|
8794 * @static |
|
8795 * @memberOf _ |
|
8796 * @category Lang |
|
8797 * @param {*} value The value to check. |
|
8798 * @returns {boolean} Returns `true` if `value` is `NaN`, else `false`. |
|
8799 * @example |
|
8800 * |
|
8801 * _.isNaN(NaN); |
|
8802 * // => true |
|
8803 * |
|
8804 * _.isNaN(new Number(NaN)); |
|
8805 * // => true |
|
8806 * |
|
8807 * isNaN(undefined); |
|
8808 * // => true |
|
8809 * |
|
8810 * _.isNaN(undefined); |
|
8811 * // => false |
|
8812 */ |
|
8813 function isNaN(value) { |
|
8814 // An `NaN` primitive is the only value that is not equal to itself. |
|
8815 // Perform the `toStringTag` check first to avoid errors with some host objects in IE. |
|
8816 return isNumber(value) && value != +value; |
|
8817 } |
|
8818 |
|
8819 /** |
|
8820 * Checks if `value` is a native function. |
|
8821 * |
|
8822 * @static |
|
8823 * @memberOf _ |
|
8824 * @category Lang |
|
8825 * @param {*} value The value to check. |
|
8826 * @returns {boolean} Returns `true` if `value` is a native function, else `false`. |
|
8827 * @example |
|
8828 * |
|
8829 * _.isNative(Array.prototype.push); |
|
8830 * // => true |
|
8831 * |
|
8832 * _.isNative(_); |
|
8833 * // => false |
|
8834 */ |
|
8835 function isNative(value) { |
|
8836 if (value == null) { |
|
8837 return false; |
|
8838 } |
|
8839 if (isFunction(value)) { |
|
8840 return reIsNative.test(fnToString.call(value)); |
|
8841 } |
|
8842 return isObjectLike(value) && reIsHostCtor.test(value); |
|
8843 } |
|
8844 |
|
8845 /** |
|
8846 * Checks if `value` is `null`. |
|
8847 * |
|
8848 * @static |
|
8849 * @memberOf _ |
|
8850 * @category Lang |
|
8851 * @param {*} value The value to check. |
|
8852 * @returns {boolean} Returns `true` if `value` is `null`, else `false`. |
|
8853 * @example |
|
8854 * |
|
8855 * _.isNull(null); |
|
8856 * // => true |
|
8857 * |
|
8858 * _.isNull(void 0); |
|
8859 * // => false |
|
8860 */ |
|
8861 function isNull(value) { |
|
8862 return value === null; |
|
8863 } |
|
8864 |
|
8865 /** |
|
8866 * Checks if `value` is classified as a `Number` primitive or object. |
|
8867 * |
|
8868 * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are classified |
|
8869 * as numbers, use the `_.isFinite` method. |
|
8870 * |
|
8871 * @static |
|
8872 * @memberOf _ |
|
8873 * @category Lang |
|
8874 * @param {*} value The value to check. |
|
8875 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8876 * @example |
|
8877 * |
|
8878 * _.isNumber(8.4); |
|
8879 * // => true |
|
8880 * |
|
8881 * _.isNumber(NaN); |
|
8882 * // => true |
|
8883 * |
|
8884 * _.isNumber('8.4'); |
|
8885 * // => false |
|
8886 */ |
|
8887 function isNumber(value) { |
|
8888 return typeof value == 'number' || (isObjectLike(value) && objToString.call(value) == numberTag); |
|
8889 } |
|
8890 |
|
8891 /** |
|
8892 * Checks if `value` is a plain object, that is, an object created by the |
|
8893 * `Object` constructor or one with a `[[Prototype]]` of `null`. |
|
8894 * |
|
8895 * **Note:** This method assumes objects created by the `Object` constructor |
|
8896 * have no inherited enumerable properties. |
|
8897 * |
|
8898 * @static |
|
8899 * @memberOf _ |
|
8900 * @category Lang |
|
8901 * @param {*} value The value to check. |
|
8902 * @returns {boolean} Returns `true` if `value` is a plain object, else `false`. |
|
8903 * @example |
|
8904 * |
|
8905 * function Foo() { |
|
8906 * this.a = 1; |
|
8907 * } |
|
8908 * |
|
8909 * _.isPlainObject(new Foo); |
|
8910 * // => false |
|
8911 * |
|
8912 * _.isPlainObject([1, 2, 3]); |
|
8913 * // => false |
|
8914 * |
|
8915 * _.isPlainObject({ 'x': 0, 'y': 0 }); |
|
8916 * // => true |
|
8917 * |
|
8918 * _.isPlainObject(Object.create(null)); |
|
8919 * // => true |
|
8920 */ |
|
8921 function isPlainObject(value) { |
|
8922 var Ctor; |
|
8923 |
|
8924 // Exit early for non `Object` objects. |
|
8925 if (!(isObjectLike(value) && objToString.call(value) == objectTag && !isArguments(value)) || |
|
8926 (!hasOwnProperty.call(value, 'constructor') && (Ctor = value.constructor, typeof Ctor == 'function' && !(Ctor instanceof Ctor)))) { |
|
8927 return false; |
|
8928 } |
|
8929 // IE < 9 iterates inherited properties before own properties. If the first |
|
8930 // iterated property is an object's own property then there are no inherited |
|
8931 // enumerable properties. |
|
8932 var result; |
|
8933 // In most environments an object's own properties are iterated before |
|
8934 // its inherited properties. If the last iterated property is an object's |
|
8935 // own property then there are no inherited enumerable properties. |
|
8936 baseForIn(value, function(subValue, key) { |
|
8937 result = key; |
|
8938 }); |
|
8939 return result === undefined || hasOwnProperty.call(value, result); |
|
8940 } |
|
8941 |
|
8942 /** |
|
8943 * Checks if `value` is classified as a `RegExp` object. |
|
8944 * |
|
8945 * @static |
|
8946 * @memberOf _ |
|
8947 * @category Lang |
|
8948 * @param {*} value The value to check. |
|
8949 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8950 * @example |
|
8951 * |
|
8952 * _.isRegExp(/abc/); |
|
8953 * // => true |
|
8954 * |
|
8955 * _.isRegExp('/abc/'); |
|
8956 * // => false |
|
8957 */ |
|
8958 function isRegExp(value) { |
|
8959 return isObject(value) && objToString.call(value) == regexpTag; |
|
8960 } |
|
8961 |
|
8962 /** |
|
8963 * Checks if `value` is classified as a `String` primitive or object. |
|
8964 * |
|
8965 * @static |
|
8966 * @memberOf _ |
|
8967 * @category Lang |
|
8968 * @param {*} value The value to check. |
|
8969 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8970 * @example |
|
8971 * |
|
8972 * _.isString('abc'); |
|
8973 * // => true |
|
8974 * |
|
8975 * _.isString(1); |
|
8976 * // => false |
|
8977 */ |
|
8978 function isString(value) { |
|
8979 return typeof value == 'string' || (isObjectLike(value) && objToString.call(value) == stringTag); |
|
8980 } |
|
8981 |
|
8982 /** |
|
8983 * Checks if `value` is classified as a typed array. |
|
8984 * |
|
8985 * @static |
|
8986 * @memberOf _ |
|
8987 * @category Lang |
|
8988 * @param {*} value The value to check. |
|
8989 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`. |
|
8990 * @example |
|
8991 * |
|
8992 * _.isTypedArray(new Uint8Array); |
|
8993 * // => true |
|
8994 * |
|
8995 * _.isTypedArray([]); |
|
8996 * // => false |
|
8997 */ |
|
8998 function isTypedArray(value) { |
|
8999 return isObjectLike(value) && isLength(value.length) && !!typedArrayTags[objToString.call(value)]; |
|
9000 } |
|
9001 |
|
9002 /** |
|
9003 * Checks if `value` is `undefined`. |
|
9004 * |
|
9005 * @static |
|
9006 * @memberOf _ |
|
9007 * @category Lang |
|
9008 * @param {*} value The value to check. |
|
9009 * @returns {boolean} Returns `true` if `value` is `undefined`, else `false`. |
|
9010 * @example |
|
9011 * |
|
9012 * _.isUndefined(void 0); |
|
9013 * // => true |
|
9014 * |
|
9015 * _.isUndefined(null); |
|
9016 * // => false |
|
9017 */ |
|
9018 function isUndefined(value) { |
|
9019 return value === undefined; |
|
9020 } |
|
9021 |
|
9022 /** |
|
9023 * Checks if `value` is less than `other`. |
|
9024 * |
|
9025 * @static |
|
9026 * @memberOf _ |
|
9027 * @category Lang |
|
9028 * @param {*} value The value to compare. |
|
9029 * @param {*} other The other value to compare. |
|
9030 * @returns {boolean} Returns `true` if `value` is less than `other`, else `false`. |
|
9031 * @example |
|
9032 * |
|
9033 * _.lt(1, 3); |
|
9034 * // => true |
|
9035 * |
|
9036 * _.lt(3, 3); |
|
9037 * // => false |
|
9038 * |
|
9039 * _.lt(3, 1); |
|
9040 * // => false |
|
9041 */ |
|
9042 function lt(value, other) { |
|
9043 return value < other; |
|
9044 } |
|
9045 |
|
9046 /** |
|
9047 * Checks if `value` is less than or equal to `other`. |
|
9048 * |
|
9049 * @static |
|
9050 * @memberOf _ |
|
9051 * @category Lang |
|
9052 * @param {*} value The value to compare. |
|
9053 * @param {*} other The other value to compare. |
|
9054 * @returns {boolean} Returns `true` if `value` is less than or equal to `other`, else `false`. |
|
9055 * @example |
|
9056 * |
|
9057 * _.lte(1, 3); |
|
9058 * // => true |
|
9059 * |
|
9060 * _.lte(3, 3); |
|
9061 * // => true |
|
9062 * |
|
9063 * _.lte(3, 1); |
|
9064 * // => false |
|
9065 */ |
|
9066 function lte(value, other) { |
|
9067 return value <= other; |
|
9068 } |
|
9069 |
|
9070 /** |
|
9071 * Converts `value` to an array. |
|
9072 * |
|
9073 * @static |
|
9074 * @memberOf _ |
|
9075 * @category Lang |
|
9076 * @param {*} value The value to convert. |
|
9077 * @returns {Array} Returns the converted array. |
|
9078 * @example |
|
9079 * |
|
9080 * (function() { |
|
9081 * return _.toArray(arguments).slice(1); |
|
9082 * }(1, 2, 3)); |
|
9083 * // => [2, 3] |
|
9084 */ |
|
9085 function toArray(value) { |
|
9086 var length = value ? getLength(value) : 0; |
|
9087 if (!isLength(length)) { |
|
9088 return values(value); |
|
9089 } |
|
9090 if (!length) { |
|
9091 return []; |
|
9092 } |
|
9093 return arrayCopy(value); |
|
9094 } |
|
9095 |
|
9096 /** |
|
9097 * Converts `value` to a plain object flattening inherited enumerable |
|
9098 * properties of `value` to own properties of the plain object. |
|
9099 * |
|
9100 * @static |
|
9101 * @memberOf _ |
|
9102 * @category Lang |
|
9103 * @param {*} value The value to convert. |
|
9104 * @returns {Object} Returns the converted plain object. |
|
9105 * @example |
|
9106 * |
|
9107 * function Foo() { |
|
9108 * this.b = 2; |
|
9109 * } |
|
9110 * |
|
9111 * Foo.prototype.c = 3; |
|
9112 * |
|
9113 * _.assign({ 'a': 1 }, new Foo); |
|
9114 * // => { 'a': 1, 'b': 2 } |
|
9115 * |
|
9116 * _.assign({ 'a': 1 }, _.toPlainObject(new Foo)); |
|
9117 * // => { 'a': 1, 'b': 2, 'c': 3 } |
|
9118 */ |
|
9119 function toPlainObject(value) { |
|
9120 return baseCopy(value, keysIn(value)); |
|
9121 } |
|
9122 |
|
9123 /*------------------------------------------------------------------------*/ |
|
9124 |
|
9125 /** |
|
9126 * Recursively merges own enumerable properties of the source object(s), that |
|
9127 * don't resolve to `undefined` into the destination object. Subsequent sources |
|
9128 * overwrite property assignments of previous sources. If `customizer` is |
|
9129 * provided it's invoked to produce the merged values of the destination and |
|
9130 * source properties. If `customizer` returns `undefined` merging is handled |
|
9131 * by the method instead. The `customizer` is bound to `thisArg` and invoked |
|
9132 * with five arguments: (objectValue, sourceValue, key, object, source). |
|
9133 * |
|
9134 * @static |
|
9135 * @memberOf _ |
|
9136 * @category Object |
|
9137 * @param {Object} object The destination object. |
|
9138 * @param {...Object} [sources] The source objects. |
|
9139 * @param {Function} [customizer] The function to customize assigned values. |
|
9140 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
9141 * @returns {Object} Returns `object`. |
|
9142 * @example |
|
9143 * |
|
9144 * var users = { |
|
9145 * 'data': [{ 'user': 'barney' }, { 'user': 'fred' }] |
|
9146 * }; |
|
9147 * |
|
9148 * var ages = { |
|
9149 * 'data': [{ 'age': 36 }, { 'age': 40 }] |
|
9150 * }; |
|
9151 * |
|
9152 * _.merge(users, ages); |
|
9153 * // => { 'data': [{ 'user': 'barney', 'age': 36 }, { 'user': 'fred', 'age': 40 }] } |
|
9154 * |
|
9155 * // using a customizer callback |
|
9156 * var object = { |
|
9157 * 'fruits': ['apple'], |
|
9158 * 'vegetables': ['beet'] |
|
9159 * }; |
|
9160 * |
|
9161 * var other = { |
|
9162 * 'fruits': ['banana'], |
|
9163 * 'vegetables': ['carrot'] |
|
9164 * }; |
|
9165 * |
|
9166 * _.merge(object, other, function(a, b) { |
|
9167 * if (_.isArray(a)) { |
|
9168 * return a.concat(b); |
|
9169 * } |
|
9170 * }); |
|
9171 * // => { 'fruits': ['apple', 'banana'], 'vegetables': ['beet', 'carrot'] } |
|
9172 */ |
|
9173 var merge = createAssigner(baseMerge); |
|
9174 |
|
9175 /** |
|
9176 * Assigns own enumerable properties of source object(s) to the destination |
|
9177 * object. Subsequent sources overwrite property assignments of previous sources. |
|
9178 * If `customizer` is provided it's invoked to produce the assigned values. |
|
9179 * The `customizer` is bound to `thisArg` and invoked with five arguments: |
|
9180 * (objectValue, sourceValue, key, object, source). |
|
9181 * |
|
9182 * **Note:** This method mutates `object` and is based on |
|
9183 * [`Object.assign`](http://ecma-international.org/ecma-262/6.0/#sec-object.assign). |
|
9184 * |
|
9185 * @static |
|
9186 * @memberOf _ |
|
9187 * @alias extend |
|
9188 * @category Object |
|
9189 * @param {Object} object The destination object. |
|
9190 * @param {...Object} [sources] The source objects. |
|
9191 * @param {Function} [customizer] The function to customize assigned values. |
|
9192 * @param {*} [thisArg] The `this` binding of `customizer`. |
|
9193 * @returns {Object} Returns `object`. |
|
9194 * @example |
|
9195 * |
|
9196 * _.assign({ 'user': 'barney' }, { 'age': 40 }, { 'user': 'fred' }); |
|
9197 * // => { 'user': 'fred', 'age': 40 } |
|
9198 * |
|
9199 * // using a customizer callback |
|
9200 * var defaults = _.partialRight(_.assign, function(value, other) { |
|
9201 * return _.isUndefined(value) ? other : value; |
|
9202 * }); |
|
9203 * |
|
9204 * defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
|
9205 * // => { 'user': 'barney', 'age': 36 } |
|
9206 */ |
|
9207 var assign = createAssigner(function(object, source, customizer) { |
|
9208 return customizer |
|
9209 ? assignWith(object, source, customizer) |
|
9210 : baseAssign(object, source); |
|
9211 }); |
|
9212 |
|
9213 /** |
|
9214 * Creates an object that inherits from the given `prototype` object. If a |
|
9215 * `properties` object is provided its own enumerable properties are assigned |
|
9216 * to the created object. |
|
9217 * |
|
9218 * @static |
|
9219 * @memberOf _ |
|
9220 * @category Object |
|
9221 * @param {Object} prototype The object to inherit from. |
|
9222 * @param {Object} [properties] The properties to assign to the object. |
|
9223 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
9224 * @returns {Object} Returns the new object. |
|
9225 * @example |
|
9226 * |
|
9227 * function Shape() { |
|
9228 * this.x = 0; |
|
9229 * this.y = 0; |
|
9230 * } |
|
9231 * |
|
9232 * function Circle() { |
|
9233 * Shape.call(this); |
|
9234 * } |
|
9235 * |
|
9236 * Circle.prototype = _.create(Shape.prototype, { |
|
9237 * 'constructor': Circle |
|
9238 * }); |
|
9239 * |
|
9240 * var circle = new Circle; |
|
9241 * circle instanceof Circle; |
|
9242 * // => true |
|
9243 * |
|
9244 * circle instanceof Shape; |
|
9245 * // => true |
|
9246 */ |
|
9247 function create(prototype, properties, guard) { |
|
9248 var result = baseCreate(prototype); |
|
9249 if (guard && isIterateeCall(prototype, properties, guard)) { |
|
9250 properties = undefined; |
|
9251 } |
|
9252 return properties ? baseAssign(result, properties) : result; |
|
9253 } |
|
9254 |
|
9255 /** |
|
9256 * Assigns own enumerable properties of source object(s) to the destination |
|
9257 * object for all destination properties that resolve to `undefined`. Once a |
|
9258 * property is set, additional values of the same property are ignored. |
|
9259 * |
|
9260 * **Note:** This method mutates `object`. |
|
9261 * |
|
9262 * @static |
|
9263 * @memberOf _ |
|
9264 * @category Object |
|
9265 * @param {Object} object The destination object. |
|
9266 * @param {...Object} [sources] The source objects. |
|
9267 * @returns {Object} Returns `object`. |
|
9268 * @example |
|
9269 * |
|
9270 * _.defaults({ 'user': 'barney' }, { 'age': 36 }, { 'user': 'fred' }); |
|
9271 * // => { 'user': 'barney', 'age': 36 } |
|
9272 */ |
|
9273 var defaults = createDefaults(assign, assignDefaults); |
|
9274 |
|
9275 /** |
|
9276 * This method is like `_.defaults` except that it recursively assigns |
|
9277 * default properties. |
|
9278 * |
|
9279 * **Note:** This method mutates `object`. |
|
9280 * |
|
9281 * @static |
|
9282 * @memberOf _ |
|
9283 * @category Object |
|
9284 * @param {Object} object The destination object. |
|
9285 * @param {...Object} [sources] The source objects. |
|
9286 * @returns {Object} Returns `object`. |
|
9287 * @example |
|
9288 * |
|
9289 * _.defaultsDeep({ 'user': { 'name': 'barney' } }, { 'user': { 'name': 'fred', 'age': 36 } }); |
|
9290 * // => { 'user': { 'name': 'barney', 'age': 36 } } |
|
9291 * |
|
9292 */ |
|
9293 var defaultsDeep = createDefaults(merge, mergeDefaults); |
|
9294 |
|
9295 /** |
|
9296 * This method is like `_.find` except that it returns the key of the first |
|
9297 * element `predicate` returns truthy for instead of the element itself. |
|
9298 * |
|
9299 * If a property name is provided for `predicate` the created `_.property` |
|
9300 * style callback returns the property value of the given element. |
|
9301 * |
|
9302 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
9303 * style callback returns `true` for elements that have a matching property |
|
9304 * value, else `false`. |
|
9305 * |
|
9306 * If an object is provided for `predicate` the created `_.matches` style |
|
9307 * callback returns `true` for elements that have the properties of the given |
|
9308 * object, else `false`. |
|
9309 * |
|
9310 * @static |
|
9311 * @memberOf _ |
|
9312 * @category Object |
|
9313 * @param {Object} object The object to search. |
|
9314 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
9315 * per iteration. |
|
9316 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
9317 * @returns {string|undefined} Returns the key of the matched element, else `undefined`. |
|
9318 * @example |
|
9319 * |
|
9320 * var users = { |
|
9321 * 'barney': { 'age': 36, 'active': true }, |
|
9322 * 'fred': { 'age': 40, 'active': false }, |
|
9323 * 'pebbles': { 'age': 1, 'active': true } |
|
9324 * }; |
|
9325 * |
|
9326 * _.findKey(users, function(chr) { |
|
9327 * return chr.age < 40; |
|
9328 * }); |
|
9329 * // => 'barney' (iteration order is not guaranteed) |
|
9330 * |
|
9331 * // using the `_.matches` callback shorthand |
|
9332 * _.findKey(users, { 'age': 1, 'active': true }); |
|
9333 * // => 'pebbles' |
|
9334 * |
|
9335 * // using the `_.matchesProperty` callback shorthand |
|
9336 * _.findKey(users, 'active', false); |
|
9337 * // => 'fred' |
|
9338 * |
|
9339 * // using the `_.property` callback shorthand |
|
9340 * _.findKey(users, 'active'); |
|
9341 * // => 'barney' |
|
9342 */ |
|
9343 var findKey = createFindKey(baseForOwn); |
|
9344 |
|
9345 /** |
|
9346 * This method is like `_.findKey` except that it iterates over elements of |
|
9347 * a collection in the opposite order. |
|
9348 * |
|
9349 * If a property name is provided for `predicate` the created `_.property` |
|
9350 * style callback returns the property value of the given element. |
|
9351 * |
|
9352 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
9353 * style callback returns `true` for elements that have a matching property |
|
9354 * value, else `false`. |
|
9355 * |
|
9356 * If an object is provided for `predicate` the created `_.matches` style |
|
9357 * callback returns `true` for elements that have the properties of the given |
|
9358 * object, else `false`. |
|
9359 * |
|
9360 * @static |
|
9361 * @memberOf _ |
|
9362 * @category Object |
|
9363 * @param {Object} object The object to search. |
|
9364 * @param {Function|Object|string} [predicate=_.identity] The function invoked |
|
9365 * per iteration. |
|
9366 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
9367 * @returns {string|undefined} Returns the key of the matched element, else `undefined`. |
|
9368 * @example |
|
9369 * |
|
9370 * var users = { |
|
9371 * 'barney': { 'age': 36, 'active': true }, |
|
9372 * 'fred': { 'age': 40, 'active': false }, |
|
9373 * 'pebbles': { 'age': 1, 'active': true } |
|
9374 * }; |
|
9375 * |
|
9376 * _.findLastKey(users, function(chr) { |
|
9377 * return chr.age < 40; |
|
9378 * }); |
|
9379 * // => returns `pebbles` assuming `_.findKey` returns `barney` |
|
9380 * |
|
9381 * // using the `_.matches` callback shorthand |
|
9382 * _.findLastKey(users, { 'age': 36, 'active': true }); |
|
9383 * // => 'barney' |
|
9384 * |
|
9385 * // using the `_.matchesProperty` callback shorthand |
|
9386 * _.findLastKey(users, 'active', false); |
|
9387 * // => 'fred' |
|
9388 * |
|
9389 * // using the `_.property` callback shorthand |
|
9390 * _.findLastKey(users, 'active'); |
|
9391 * // => 'pebbles' |
|
9392 */ |
|
9393 var findLastKey = createFindKey(baseForOwnRight); |
|
9394 |
|
9395 /** |
|
9396 * Iterates over own and inherited enumerable properties of an object invoking |
|
9397 * `iteratee` for each property. The `iteratee` is bound to `thisArg` and invoked |
|
9398 * with three arguments: (value, key, object). Iteratee functions may exit |
|
9399 * iteration early by explicitly returning `false`. |
|
9400 * |
|
9401 * @static |
|
9402 * @memberOf _ |
|
9403 * @category Object |
|
9404 * @param {Object} object The object to iterate over. |
|
9405 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
9406 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9407 * @returns {Object} Returns `object`. |
|
9408 * @example |
|
9409 * |
|
9410 * function Foo() { |
|
9411 * this.a = 1; |
|
9412 * this.b = 2; |
|
9413 * } |
|
9414 * |
|
9415 * Foo.prototype.c = 3; |
|
9416 * |
|
9417 * _.forIn(new Foo, function(value, key) { |
|
9418 * console.log(key); |
|
9419 * }); |
|
9420 * // => logs 'a', 'b', and 'c' (iteration order is not guaranteed) |
|
9421 */ |
|
9422 var forIn = createForIn(baseFor); |
|
9423 |
|
9424 /** |
|
9425 * This method is like `_.forIn` except that it iterates over properties of |
|
9426 * `object` in the opposite order. |
|
9427 * |
|
9428 * @static |
|
9429 * @memberOf _ |
|
9430 * @category Object |
|
9431 * @param {Object} object The object to iterate over. |
|
9432 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
9433 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9434 * @returns {Object} Returns `object`. |
|
9435 * @example |
|
9436 * |
|
9437 * function Foo() { |
|
9438 * this.a = 1; |
|
9439 * this.b = 2; |
|
9440 * } |
|
9441 * |
|
9442 * Foo.prototype.c = 3; |
|
9443 * |
|
9444 * _.forInRight(new Foo, function(value, key) { |
|
9445 * console.log(key); |
|
9446 * }); |
|
9447 * // => logs 'c', 'b', and 'a' assuming `_.forIn ` logs 'a', 'b', and 'c' |
|
9448 */ |
|
9449 var forInRight = createForIn(baseForRight); |
|
9450 |
|
9451 /** |
|
9452 * Iterates over own enumerable properties of an object invoking `iteratee` |
|
9453 * for each property. The `iteratee` is bound to `thisArg` and invoked with |
|
9454 * three arguments: (value, key, object). Iteratee functions may exit iteration |
|
9455 * early by explicitly returning `false`. |
|
9456 * |
|
9457 * @static |
|
9458 * @memberOf _ |
|
9459 * @category Object |
|
9460 * @param {Object} object The object to iterate over. |
|
9461 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
9462 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9463 * @returns {Object} Returns `object`. |
|
9464 * @example |
|
9465 * |
|
9466 * function Foo() { |
|
9467 * this.a = 1; |
|
9468 * this.b = 2; |
|
9469 * } |
|
9470 * |
|
9471 * Foo.prototype.c = 3; |
|
9472 * |
|
9473 * _.forOwn(new Foo, function(value, key) { |
|
9474 * console.log(key); |
|
9475 * }); |
|
9476 * // => logs 'a' and 'b' (iteration order is not guaranteed) |
|
9477 */ |
|
9478 var forOwn = createForOwn(baseForOwn); |
|
9479 |
|
9480 /** |
|
9481 * This method is like `_.forOwn` except that it iterates over properties of |
|
9482 * `object` in the opposite order. |
|
9483 * |
|
9484 * @static |
|
9485 * @memberOf _ |
|
9486 * @category Object |
|
9487 * @param {Object} object The object to iterate over. |
|
9488 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
9489 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9490 * @returns {Object} Returns `object`. |
|
9491 * @example |
|
9492 * |
|
9493 * function Foo() { |
|
9494 * this.a = 1; |
|
9495 * this.b = 2; |
|
9496 * } |
|
9497 * |
|
9498 * Foo.prototype.c = 3; |
|
9499 * |
|
9500 * _.forOwnRight(new Foo, function(value, key) { |
|
9501 * console.log(key); |
|
9502 * }); |
|
9503 * // => logs 'b' and 'a' assuming `_.forOwn` logs 'a' and 'b' |
|
9504 */ |
|
9505 var forOwnRight = createForOwn(baseForOwnRight); |
|
9506 |
|
9507 /** |
|
9508 * Creates an array of function property names from all enumerable properties, |
|
9509 * own and inherited, of `object`. |
|
9510 * |
|
9511 * @static |
|
9512 * @memberOf _ |
|
9513 * @alias methods |
|
9514 * @category Object |
|
9515 * @param {Object} object The object to inspect. |
|
9516 * @returns {Array} Returns the new array of property names. |
|
9517 * @example |
|
9518 * |
|
9519 * _.functions(_); |
|
9520 * // => ['after', 'ary', 'assign', ...] |
|
9521 */ |
|
9522 function functions(object) { |
|
9523 return baseFunctions(object, keysIn(object)); |
|
9524 } |
|
9525 |
|
9526 /** |
|
9527 * Gets the property value at `path` of `object`. If the resolved value is |
|
9528 * `undefined` the `defaultValue` is used in its place. |
|
9529 * |
|
9530 * @static |
|
9531 * @memberOf _ |
|
9532 * @category Object |
|
9533 * @param {Object} object The object to query. |
|
9534 * @param {Array|string} path The path of the property to get. |
|
9535 * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. |
|
9536 * @returns {*} Returns the resolved value. |
|
9537 * @example |
|
9538 * |
|
9539 * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
|
9540 * |
|
9541 * _.get(object, 'a[0].b.c'); |
|
9542 * // => 3 |
|
9543 * |
|
9544 * _.get(object, ['a', '0', 'b', 'c']); |
|
9545 * // => 3 |
|
9546 * |
|
9547 * _.get(object, 'a.b.c', 'default'); |
|
9548 * // => 'default' |
|
9549 */ |
|
9550 function get(object, path, defaultValue) { |
|
9551 var result = object == null ? undefined : baseGet(object, toPath(path), (path + '')); |
|
9552 return result === undefined ? defaultValue : result; |
|
9553 } |
|
9554 |
|
9555 /** |
|
9556 * Checks if `path` is a direct property. |
|
9557 * |
|
9558 * @static |
|
9559 * @memberOf _ |
|
9560 * @category Object |
|
9561 * @param {Object} object The object to query. |
|
9562 * @param {Array|string} path The path to check. |
|
9563 * @returns {boolean} Returns `true` if `path` is a direct property, else `false`. |
|
9564 * @example |
|
9565 * |
|
9566 * var object = { 'a': { 'b': { 'c': 3 } } }; |
|
9567 * |
|
9568 * _.has(object, 'a'); |
|
9569 * // => true |
|
9570 * |
|
9571 * _.has(object, 'a.b.c'); |
|
9572 * // => true |
|
9573 * |
|
9574 * _.has(object, ['a', 'b', 'c']); |
|
9575 * // => true |
|
9576 */ |
|
9577 function has(object, path) { |
|
9578 if (object == null) { |
|
9579 return false; |
|
9580 } |
|
9581 var result = hasOwnProperty.call(object, path); |
|
9582 if (!result && !isKey(path)) { |
|
9583 path = toPath(path); |
|
9584 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
|
9585 if (object == null) { |
|
9586 return false; |
|
9587 } |
|
9588 path = last(path); |
|
9589 result = hasOwnProperty.call(object, path); |
|
9590 } |
|
9591 return result || (isLength(object.length) && isIndex(path, object.length) && |
|
9592 (isArray(object) || isArguments(object))); |
|
9593 } |
|
9594 |
|
9595 /** |
|
9596 * Creates an object composed of the inverted keys and values of `object`. |
|
9597 * If `object` contains duplicate values, subsequent values overwrite property |
|
9598 * assignments of previous values unless `multiValue` is `true`. |
|
9599 * |
|
9600 * @static |
|
9601 * @memberOf _ |
|
9602 * @category Object |
|
9603 * @param {Object} object The object to invert. |
|
9604 * @param {boolean} [multiValue] Allow multiple values per key. |
|
9605 * @param- {Object} [guard] Enables use as a callback for functions like `_.map`. |
|
9606 * @returns {Object} Returns the new inverted object. |
|
9607 * @example |
|
9608 * |
|
9609 * var object = { 'a': 1, 'b': 2, 'c': 1 }; |
|
9610 * |
|
9611 * _.invert(object); |
|
9612 * // => { '1': 'c', '2': 'b' } |
|
9613 * |
|
9614 * // with `multiValue` |
|
9615 * _.invert(object, true); |
|
9616 * // => { '1': ['a', 'c'], '2': ['b'] } |
|
9617 */ |
|
9618 function invert(object, multiValue, guard) { |
|
9619 if (guard && isIterateeCall(object, multiValue, guard)) { |
|
9620 multiValue = undefined; |
|
9621 } |
|
9622 var index = -1, |
|
9623 props = keys(object), |
|
9624 length = props.length, |
|
9625 result = {}; |
|
9626 |
|
9627 while (++index < length) { |
|
9628 var key = props[index], |
|
9629 value = object[key]; |
|
9630 |
|
9631 if (multiValue) { |
|
9632 if (hasOwnProperty.call(result, value)) { |
|
9633 result[value].push(key); |
|
9634 } else { |
|
9635 result[value] = [key]; |
5825 } |
9636 } |
5826 } |
9637 } |
5827 return result; |
9638 else { |
5828 }; |
9639 result[value] = key; |
5829 } |
9640 } |
5830 |
9641 } |
5831 /** |
9642 return result; |
5832 * Converts the characters `&`, `<`, `>`, `"`, and `'` in `string` to their |
9643 } |
5833 * corresponding HTML entities. |
9644 |
5834 * |
9645 /** |
5835 * @static |
9646 * Creates an array of the own enumerable property names of `object`. |
5836 * @memberOf _ |
9647 * |
5837 * @category Utilities |
9648 * **Note:** Non-object values are coerced to objects. See the |
5838 * @param {string} string The string to escape. |
9649 * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) |
5839 * @returns {string} Returns the escaped string. |
9650 * for more details. |
5840 * @example |
9651 * |
5841 * |
9652 * @static |
5842 * _.escape('Fred, Wilma, & Pebbles'); |
9653 * @memberOf _ |
5843 * // => 'Fred, Wilma, & Pebbles' |
9654 * @category Object |
5844 */ |
9655 * @param {Object} object The object to query. |
5845 function escape(string) { |
9656 * @returns {Array} Returns the array of property names. |
5846 return string == null ? '' : String(string).replace(reUnescapedHtml, escapeHtmlChar); |
9657 * @example |
5847 } |
9658 * |
5848 |
9659 * function Foo() { |
5849 /** |
9660 * this.a = 1; |
5850 * This method returns the first argument provided to it. |
9661 * this.b = 2; |
5851 * |
9662 * } |
5852 * @static |
9663 * |
5853 * @memberOf _ |
9664 * Foo.prototype.c = 3; |
5854 * @category Utilities |
9665 * |
5855 * @param {*} value Any value. |
9666 * _.keys(new Foo); |
5856 * @returns {*} Returns `value`. |
9667 * // => ['a', 'b'] (iteration order is not guaranteed) |
5857 * @example |
9668 * |
5858 * |
9669 * _.keys('hi'); |
5859 * var object = { 'name': 'fred' }; |
9670 * // => ['0', '1'] |
5860 * _.identity(object) === object; |
9671 */ |
|
9672 var keys = !nativeKeys ? shimKeys : function(object) { |
|
9673 var Ctor = object == null ? undefined : object.constructor; |
|
9674 if ((typeof Ctor == 'function' && Ctor.prototype === object) || |
|
9675 (typeof object != 'function' && isArrayLike(object))) { |
|
9676 return shimKeys(object); |
|
9677 } |
|
9678 return isObject(object) ? nativeKeys(object) : []; |
|
9679 }; |
|
9680 |
|
9681 /** |
|
9682 * Creates an array of the own and inherited enumerable property names of `object`. |
|
9683 * |
|
9684 * **Note:** Non-object values are coerced to objects. |
|
9685 * |
|
9686 * @static |
|
9687 * @memberOf _ |
|
9688 * @category Object |
|
9689 * @param {Object} object The object to query. |
|
9690 * @returns {Array} Returns the array of property names. |
|
9691 * @example |
|
9692 * |
|
9693 * function Foo() { |
|
9694 * this.a = 1; |
|
9695 * this.b = 2; |
|
9696 * } |
|
9697 * |
|
9698 * Foo.prototype.c = 3; |
|
9699 * |
|
9700 * _.keysIn(new Foo); |
|
9701 * // => ['a', 'b', 'c'] (iteration order is not guaranteed) |
|
9702 */ |
|
9703 function keysIn(object) { |
|
9704 if (object == null) { |
|
9705 return []; |
|
9706 } |
|
9707 if (!isObject(object)) { |
|
9708 object = Object(object); |
|
9709 } |
|
9710 var length = object.length; |
|
9711 length = (length && isLength(length) && |
|
9712 (isArray(object) || isArguments(object)) && length) || 0; |
|
9713 |
|
9714 var Ctor = object.constructor, |
|
9715 index = -1, |
|
9716 isProto = typeof Ctor == 'function' && Ctor.prototype === object, |
|
9717 result = Array(length), |
|
9718 skipIndexes = length > 0; |
|
9719 |
|
9720 while (++index < length) { |
|
9721 result[index] = (index + ''); |
|
9722 } |
|
9723 for (var key in object) { |
|
9724 if (!(skipIndexes && isIndex(key, length)) && |
|
9725 !(key == 'constructor' && (isProto || !hasOwnProperty.call(object, key)))) { |
|
9726 result.push(key); |
|
9727 } |
|
9728 } |
|
9729 return result; |
|
9730 } |
|
9731 |
|
9732 /** |
|
9733 * The opposite of `_.mapValues`; this method creates an object with the |
|
9734 * same values as `object` and keys generated by running each own enumerable |
|
9735 * property of `object` through `iteratee`. |
|
9736 * |
|
9737 * @static |
|
9738 * @memberOf _ |
|
9739 * @category Object |
|
9740 * @param {Object} object The object to iterate over. |
|
9741 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
9742 * per iteration. |
|
9743 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9744 * @returns {Object} Returns the new mapped object. |
|
9745 * @example |
|
9746 * |
|
9747 * _.mapKeys({ 'a': 1, 'b': 2 }, function(value, key) { |
|
9748 * return key + value; |
|
9749 * }); |
|
9750 * // => { 'a1': 1, 'b2': 2 } |
|
9751 */ |
|
9752 var mapKeys = createObjectMapper(true); |
|
9753 |
|
9754 /** |
|
9755 * Creates an object with the same keys as `object` and values generated by |
|
9756 * running each own enumerable property of `object` through `iteratee`. The |
|
9757 * iteratee function is bound to `thisArg` and invoked with three arguments: |
|
9758 * (value, key, object). |
|
9759 * |
|
9760 * If a property name is provided for `iteratee` the created `_.property` |
|
9761 * style callback returns the property value of the given element. |
|
9762 * |
|
9763 * If a value is also provided for `thisArg` the created `_.matchesProperty` |
|
9764 * style callback returns `true` for elements that have a matching property |
|
9765 * value, else `false`. |
|
9766 * |
|
9767 * If an object is provided for `iteratee` the created `_.matches` style |
|
9768 * callback returns `true` for elements that have the properties of the given |
|
9769 * object, else `false`. |
|
9770 * |
|
9771 * @static |
|
9772 * @memberOf _ |
|
9773 * @category Object |
|
9774 * @param {Object} object The object to iterate over. |
|
9775 * @param {Function|Object|string} [iteratee=_.identity] The function invoked |
|
9776 * per iteration. |
|
9777 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
9778 * @returns {Object} Returns the new mapped object. |
|
9779 * @example |
|
9780 * |
|
9781 * _.mapValues({ 'a': 1, 'b': 2 }, function(n) { |
|
9782 * return n * 3; |
|
9783 * }); |
|
9784 * // => { 'a': 3, 'b': 6 } |
|
9785 * |
|
9786 * var users = { |
|
9787 * 'fred': { 'user': 'fred', 'age': 40 }, |
|
9788 * 'pebbles': { 'user': 'pebbles', 'age': 1 } |
|
9789 * }; |
|
9790 * |
|
9791 * // using the `_.property` callback shorthand |
|
9792 * _.mapValues(users, 'age'); |
|
9793 * // => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed) |
|
9794 */ |
|
9795 var mapValues = createObjectMapper(); |
|
9796 |
|
9797 /** |
|
9798 * The opposite of `_.pick`; this method creates an object composed of the |
|
9799 * own and inherited enumerable properties of `object` that are not omitted. |
|
9800 * |
|
9801 * @static |
|
9802 * @memberOf _ |
|
9803 * @category Object |
|
9804 * @param {Object} object The source object. |
|
9805 * @param {Function|...(string|string[])} [predicate] The function invoked per |
|
9806 * iteration or property names to omit, specified as individual property |
|
9807 * names or arrays of property names. |
|
9808 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
9809 * @returns {Object} Returns the new object. |
|
9810 * @example |
|
9811 * |
|
9812 * var object = { 'user': 'fred', 'age': 40 }; |
|
9813 * |
|
9814 * _.omit(object, 'age'); |
|
9815 * // => { 'user': 'fred' } |
|
9816 * |
|
9817 * _.omit(object, _.isNumber); |
|
9818 * // => { 'user': 'fred' } |
|
9819 */ |
|
9820 var omit = restParam(function(object, props) { |
|
9821 if (object == null) { |
|
9822 return {}; |
|
9823 } |
|
9824 if (typeof props[0] != 'function') { |
|
9825 var props = arrayMap(baseFlatten(props), String); |
|
9826 return pickByArray(object, baseDifference(keysIn(object), props)); |
|
9827 } |
|
9828 var predicate = bindCallback(props[0], props[1], 3); |
|
9829 return pickByCallback(object, function(value, key, object) { |
|
9830 return !predicate(value, key, object); |
|
9831 }); |
|
9832 }); |
|
9833 |
|
9834 /** |
|
9835 * Creates a two dimensional array of the key-value pairs for `object`, |
|
9836 * e.g. `[[key1, value1], [key2, value2]]`. |
|
9837 * |
|
9838 * @static |
|
9839 * @memberOf _ |
|
9840 * @category Object |
|
9841 * @param {Object} object The object to query. |
|
9842 * @returns {Array} Returns the new array of key-value pairs. |
|
9843 * @example |
|
9844 * |
|
9845 * _.pairs({ 'barney': 36, 'fred': 40 }); |
|
9846 * // => [['barney', 36], ['fred', 40]] (iteration order is not guaranteed) |
|
9847 */ |
|
9848 function pairs(object) { |
|
9849 object = toObject(object); |
|
9850 |
|
9851 var index = -1, |
|
9852 props = keys(object), |
|
9853 length = props.length, |
|
9854 result = Array(length); |
|
9855 |
|
9856 while (++index < length) { |
|
9857 var key = props[index]; |
|
9858 result[index] = [key, object[key]]; |
|
9859 } |
|
9860 return result; |
|
9861 } |
|
9862 |
|
9863 /** |
|
9864 * Creates an object composed of the picked `object` properties. Property |
|
9865 * names may be specified as individual arguments or as arrays of property |
|
9866 * names. If `predicate` is provided it's invoked for each property of `object` |
|
9867 * picking the properties `predicate` returns truthy for. The predicate is |
|
9868 * bound to `thisArg` and invoked with three arguments: (value, key, object). |
|
9869 * |
|
9870 * @static |
|
9871 * @memberOf _ |
|
9872 * @category Object |
|
9873 * @param {Object} object The source object. |
|
9874 * @param {Function|...(string|string[])} [predicate] The function invoked per |
|
9875 * iteration or property names to pick, specified as individual property |
|
9876 * names or arrays of property names. |
|
9877 * @param {*} [thisArg] The `this` binding of `predicate`. |
|
9878 * @returns {Object} Returns the new object. |
|
9879 * @example |
|
9880 * |
|
9881 * var object = { 'user': 'fred', 'age': 40 }; |
|
9882 * |
|
9883 * _.pick(object, 'user'); |
|
9884 * // => { 'user': 'fred' } |
|
9885 * |
|
9886 * _.pick(object, _.isString); |
|
9887 * // => { 'user': 'fred' } |
|
9888 */ |
|
9889 var pick = restParam(function(object, props) { |
|
9890 if (object == null) { |
|
9891 return {}; |
|
9892 } |
|
9893 return typeof props[0] == 'function' |
|
9894 ? pickByCallback(object, bindCallback(props[0], props[1], 3)) |
|
9895 : pickByArray(object, baseFlatten(props)); |
|
9896 }); |
|
9897 |
|
9898 /** |
|
9899 * This method is like `_.get` except that if the resolved value is a function |
|
9900 * it's invoked with the `this` binding of its parent object and its result |
|
9901 * is returned. |
|
9902 * |
|
9903 * @static |
|
9904 * @memberOf _ |
|
9905 * @category Object |
|
9906 * @param {Object} object The object to query. |
|
9907 * @param {Array|string} path The path of the property to resolve. |
|
9908 * @param {*} [defaultValue] The value returned if the resolved value is `undefined`. |
|
9909 * @returns {*} Returns the resolved value. |
|
9910 * @example |
|
9911 * |
|
9912 * var object = { 'a': [{ 'b': { 'c1': 3, 'c2': _.constant(4) } }] }; |
|
9913 * |
|
9914 * _.result(object, 'a[0].b.c1'); |
|
9915 * // => 3 |
|
9916 * |
|
9917 * _.result(object, 'a[0].b.c2'); |
|
9918 * // => 4 |
|
9919 * |
|
9920 * _.result(object, 'a.b.c', 'default'); |
|
9921 * // => 'default' |
|
9922 * |
|
9923 * _.result(object, 'a.b.c', _.constant('default')); |
|
9924 * // => 'default' |
|
9925 */ |
|
9926 function result(object, path, defaultValue) { |
|
9927 var result = object == null ? undefined : object[path]; |
|
9928 if (result === undefined) { |
|
9929 if (object != null && !isKey(path, object)) { |
|
9930 path = toPath(path); |
|
9931 object = path.length == 1 ? object : baseGet(object, baseSlice(path, 0, -1)); |
|
9932 result = object == null ? undefined : object[last(path)]; |
|
9933 } |
|
9934 result = result === undefined ? defaultValue : result; |
|
9935 } |
|
9936 return isFunction(result) ? result.call(object) : result; |
|
9937 } |
|
9938 |
|
9939 /** |
|
9940 * Sets the property value of `path` on `object`. If a portion of `path` |
|
9941 * does not exist it's created. |
|
9942 * |
|
9943 * @static |
|
9944 * @memberOf _ |
|
9945 * @category Object |
|
9946 * @param {Object} object The object to augment. |
|
9947 * @param {Array|string} path The path of the property to set. |
|
9948 * @param {*} value The value to set. |
|
9949 * @returns {Object} Returns `object`. |
|
9950 * @example |
|
9951 * |
|
9952 * var object = { 'a': [{ 'b': { 'c': 3 } }] }; |
|
9953 * |
|
9954 * _.set(object, 'a[0].b.c', 4); |
|
9955 * console.log(object.a[0].b.c); |
|
9956 * // => 4 |
|
9957 * |
|
9958 * _.set(object, 'x[0].y.z', 5); |
|
9959 * console.log(object.x[0].y.z); |
|
9960 * // => 5 |
|
9961 */ |
|
9962 function set(object, path, value) { |
|
9963 if (object == null) { |
|
9964 return object; |
|
9965 } |
|
9966 var pathKey = (path + ''); |
|
9967 path = (object[pathKey] != null || isKey(path, object)) ? [pathKey] : toPath(path); |
|
9968 |
|
9969 var index = -1, |
|
9970 length = path.length, |
|
9971 lastIndex = length - 1, |
|
9972 nested = object; |
|
9973 |
|
9974 while (nested != null && ++index < length) { |
|
9975 var key = path[index]; |
|
9976 if (isObject(nested)) { |
|
9977 if (index == lastIndex) { |
|
9978 nested[key] = value; |
|
9979 } else if (nested[key] == null) { |
|
9980 nested[key] = isIndex(path[index + 1]) ? [] : {}; |
|
9981 } |
|
9982 } |
|
9983 nested = nested[key]; |
|
9984 } |
|
9985 return object; |
|
9986 } |
|
9987 |
|
9988 /** |
|
9989 * An alternative to `_.reduce`; this method transforms `object` to a new |
|
9990 * `accumulator` object which is the result of running each of its own enumerable |
|
9991 * properties through `iteratee`, with each invocation potentially mutating |
|
9992 * the `accumulator` object. The `iteratee` is bound to `thisArg` and invoked |
|
9993 * with four arguments: (accumulator, value, key, object). Iteratee functions |
|
9994 * may exit iteration early by explicitly returning `false`. |
|
9995 * |
|
9996 * @static |
|
9997 * @memberOf _ |
|
9998 * @category Object |
|
9999 * @param {Array|Object} object The object to iterate over. |
|
10000 * @param {Function} [iteratee=_.identity] The function invoked per iteration. |
|
10001 * @param {*} [accumulator] The custom accumulator value. |
|
10002 * @param {*} [thisArg] The `this` binding of `iteratee`. |
|
10003 * @returns {*} Returns the accumulated value. |
|
10004 * @example |
|
10005 * |
|
10006 * _.transform([2, 3, 4], function(result, n) { |
|
10007 * result.push(n *= n); |
|
10008 * return n % 2 == 0; |
|
10009 * }); |
|
10010 * // => [4, 9] |
|
10011 * |
|
10012 * _.transform({ 'a': 1, 'b': 2 }, function(result, n, key) { |
|
10013 * result[key] = n * 3; |
|
10014 * }); |
|
10015 * // => { 'a': 3, 'b': 6 } |
|
10016 */ |
|
10017 function transform(object, iteratee, accumulator, thisArg) { |
|
10018 var isArr = isArray(object) || isTypedArray(object); |
|
10019 iteratee = getCallback(iteratee, thisArg, 4); |
|
10020 |
|
10021 if (accumulator == null) { |
|
10022 if (isArr || isObject(object)) { |
|
10023 var Ctor = object.constructor; |
|
10024 if (isArr) { |
|
10025 accumulator = isArray(object) ? new Ctor : []; |
|
10026 } else { |
|
10027 accumulator = baseCreate(isFunction(Ctor) ? Ctor.prototype : undefined); |
|
10028 } |
|
10029 } else { |
|
10030 accumulator = {}; |
|
10031 } |
|
10032 } |
|
10033 (isArr ? arrayEach : baseForOwn)(object, function(value, index, object) { |
|
10034 return iteratee(accumulator, value, index, object); |
|
10035 }); |
|
10036 return accumulator; |
|
10037 } |
|
10038 |
|
10039 /** |
|
10040 * Creates an array of the own enumerable property values of `object`. |
|
10041 * |
|
10042 * **Note:** Non-object values are coerced to objects. |
|
10043 * |
|
10044 * @static |
|
10045 * @memberOf _ |
|
10046 * @category Object |
|
10047 * @param {Object} object The object to query. |
|
10048 * @returns {Array} Returns the array of property values. |
|
10049 * @example |
|
10050 * |
|
10051 * function Foo() { |
|
10052 * this.a = 1; |
|
10053 * this.b = 2; |
|
10054 * } |
|
10055 * |
|
10056 * Foo.prototype.c = 3; |
|
10057 * |
|
10058 * _.values(new Foo); |
|
10059 * // => [1, 2] (iteration order is not guaranteed) |
|
10060 * |
|
10061 * _.values('hi'); |
|
10062 * // => ['h', 'i'] |
|
10063 */ |
|
10064 function values(object) { |
|
10065 return baseValues(object, keys(object)); |
|
10066 } |
|
10067 |
|
10068 /** |
|
10069 * Creates an array of the own and inherited enumerable property values |
|
10070 * of `object`. |
|
10071 * |
|
10072 * **Note:** Non-object values are coerced to objects. |
|
10073 * |
|
10074 * @static |
|
10075 * @memberOf _ |
|
10076 * @category Object |
|
10077 * @param {Object} object The object to query. |
|
10078 * @returns {Array} Returns the array of property values. |
|
10079 * @example |
|
10080 * |
|
10081 * function Foo() { |
|
10082 * this.a = 1; |
|
10083 * this.b = 2; |
|
10084 * } |
|
10085 * |
|
10086 * Foo.prototype.c = 3; |
|
10087 * |
|
10088 * _.valuesIn(new Foo); |
|
10089 * // => [1, 2, 3] (iteration order is not guaranteed) |
|
10090 */ |
|
10091 function valuesIn(object) { |
|
10092 return baseValues(object, keysIn(object)); |
|
10093 } |
|
10094 |
|
10095 /*------------------------------------------------------------------------*/ |
|
10096 |
|
10097 /** |
|
10098 * Checks if `n` is between `start` and up to but not including, `end`. If |
|
10099 * `end` is not specified it's set to `start` with `start` then set to `0`. |
|
10100 * |
|
10101 * @static |
|
10102 * @memberOf _ |
|
10103 * @category Number |
|
10104 * @param {number} n The number to check. |
|
10105 * @param {number} [start=0] The start of the range. |
|
10106 * @param {number} end The end of the range. |
|
10107 * @returns {boolean} Returns `true` if `n` is in the range, else `false`. |
|
10108 * @example |
|
10109 * |
|
10110 * _.inRange(3, 2, 4); |
5861 * // => true |
10111 * // => true |
5862 */ |
10112 * |
5863 function identity(value) { |
10113 * _.inRange(4, 8); |
5864 return value; |
|
5865 } |
|
5866 |
|
5867 /** |
|
5868 * Adds function properties of a source object to the destination object. |
|
5869 * If `object` is a function methods will be added to its prototype as well. |
|
5870 * |
|
5871 * @static |
|
5872 * @memberOf _ |
|
5873 * @category Utilities |
|
5874 * @param {Function|Object} [object=lodash] object The destination object. |
|
5875 * @param {Object} source The object of functions to add. |
|
5876 * @param {Object} [options] The options object. |
|
5877 * @param {boolean} [options.chain=true] Specify whether the functions added are chainable. |
|
5878 * @example |
|
5879 * |
|
5880 * function capitalize(string) { |
|
5881 * return string.charAt(0).toUpperCase() + string.slice(1).toLowerCase(); |
|
5882 * } |
|
5883 * |
|
5884 * _.mixin({ 'capitalize': capitalize }); |
|
5885 * _.capitalize('fred'); |
|
5886 * // => 'Fred' |
|
5887 * |
|
5888 * _('fred').capitalize().value(); |
|
5889 * // => 'Fred' |
|
5890 * |
|
5891 * _.mixin({ 'capitalize': capitalize }, { 'chain': false }); |
|
5892 * _('fred').capitalize(); |
|
5893 * // => 'Fred' |
|
5894 */ |
|
5895 function mixin(object, source, options) { |
|
5896 var chain = true, |
|
5897 methodNames = source && functions(source); |
|
5898 |
|
5899 if (!source || (!options && !methodNames.length)) { |
|
5900 if (options == null) { |
|
5901 options = source; |
|
5902 } |
|
5903 ctor = lodashWrapper; |
|
5904 source = object; |
|
5905 object = lodash; |
|
5906 methodNames = functions(source); |
|
5907 } |
|
5908 if (options === false) { |
|
5909 chain = false; |
|
5910 } else if (isObject(options) && 'chain' in options) { |
|
5911 chain = options.chain; |
|
5912 } |
|
5913 var ctor = object, |
|
5914 isFunc = isFunction(ctor); |
|
5915 |
|
5916 forEach(methodNames, function(methodName) { |
|
5917 var func = object[methodName] = source[methodName]; |
|
5918 if (isFunc) { |
|
5919 ctor.prototype[methodName] = function() { |
|
5920 var chainAll = this.__chain__, |
|
5921 value = this.__wrapped__, |
|
5922 args = [value]; |
|
5923 |
|
5924 push.apply(args, arguments); |
|
5925 var result = func.apply(object, args); |
|
5926 if (chain || chainAll) { |
|
5927 if (value === result && isObject(result)) { |
|
5928 return this; |
|
5929 } |
|
5930 result = new ctor(result); |
|
5931 result.__chain__ = chainAll; |
|
5932 } |
|
5933 return result; |
|
5934 }; |
|
5935 } |
|
5936 }); |
|
5937 } |
|
5938 |
|
5939 /** |
|
5940 * Reverts the '_' variable to its previous value and returns a reference to |
|
5941 * the `lodash` function. |
|
5942 * |
|
5943 * @static |
|
5944 * @memberOf _ |
|
5945 * @category Utilities |
|
5946 * @returns {Function} Returns the `lodash` function. |
|
5947 * @example |
|
5948 * |
|
5949 * var lodash = _.noConflict(); |
|
5950 */ |
|
5951 function noConflict() { |
|
5952 context._ = oldDash; |
|
5953 return this; |
|
5954 } |
|
5955 |
|
5956 /** |
|
5957 * A no-operation function. |
|
5958 * |
|
5959 * @static |
|
5960 * @memberOf _ |
|
5961 * @category Utilities |
|
5962 * @example |
|
5963 * |
|
5964 * var object = { 'name': 'fred' }; |
|
5965 * _.noop(object) === undefined; |
|
5966 * // => true |
10114 * // => true |
5967 */ |
10115 * |
5968 function noop() { |
10116 * _.inRange(4, 2); |
5969 // no operation performed |
10117 * // => false |
5970 } |
10118 * |
5971 |
10119 * _.inRange(2, 2); |
5972 /** |
10120 * // => false |
5973 * Gets the number of milliseconds that have elapsed since the Unix epoch |
10121 * |
5974 * (1 January 1970 00:00:00 UTC). |
10122 * _.inRange(1.2, 2); |
5975 * |
10123 * // => true |
5976 * @static |
10124 * |
5977 * @memberOf _ |
10125 * _.inRange(5.2, 4); |
5978 * @category Utilities |
10126 * // => false |
5979 * @example |
10127 */ |
5980 * |
10128 function inRange(value, start, end) { |
5981 * var stamp = _.now(); |
10129 start = +start || 0; |
5982 * _.defer(function() { console.log(_.now() - stamp); }); |
10130 if (end === undefined) { |
5983 * // => logs the number of milliseconds it took for the deferred function to be called |
10131 end = start; |
5984 */ |
10132 start = 0; |
5985 var now = isNative(now = Date.now) && now || function() { |
10133 } else { |
5986 return new Date().getTime(); |
10134 end = +end || 0; |
5987 }; |
10135 } |
5988 |
10136 return value >= nativeMin(start, end) && value < nativeMax(start, end); |
5989 /** |
|
5990 * Converts the given value into an integer of the specified radix. |
|
5991 * If `radix` is `undefined` or `0` a `radix` of `10` is used unless the |
|
5992 * `value` is a hexadecimal, in which case a `radix` of `16` is used. |
|
5993 * |
|
5994 * Note: This method avoids differences in native ES3 and ES5 `parseInt` |
|
5995 * implementations. See http://es5.github.io/#E. |
|
5996 * |
|
5997 * @static |
|
5998 * @memberOf _ |
|
5999 * @category Utilities |
|
6000 * @param {string} value The value to parse. |
|
6001 * @param {number} [radix] The radix used to interpret the value to parse. |
|
6002 * @returns {number} Returns the new integer value. |
|
6003 * @example |
|
6004 * |
|
6005 * _.parseInt('08'); |
|
6006 * // => 8 |
|
6007 */ |
|
6008 var parseInt = nativeParseInt(whitespace + '08') == 8 ? nativeParseInt : function(value, radix) { |
|
6009 // Firefox < 21 and Opera < 15 follow the ES3 specified implementation of `parseInt` |
|
6010 return nativeParseInt(isString(value) ? value.replace(reLeadingSpacesAndZeros, '') : value, radix || 0); |
|
6011 }; |
|
6012 |
|
6013 /** |
|
6014 * Creates a "_.pluck" style function, which returns the `key` value of a |
|
6015 * given object. |
|
6016 * |
|
6017 * @static |
|
6018 * @memberOf _ |
|
6019 * @category Utilities |
|
6020 * @param {string} key The name of the property to retrieve. |
|
6021 * @returns {Function} Returns the new function. |
|
6022 * @example |
|
6023 * |
|
6024 * var characters = [ |
|
6025 * { 'name': 'fred', 'age': 40 }, |
|
6026 * { 'name': 'barney', 'age': 36 } |
|
6027 * ]; |
|
6028 * |
|
6029 * var getName = _.property('name'); |
|
6030 * |
|
6031 * _.map(characters, getName); |
|
6032 * // => ['barney', 'fred'] |
|
6033 * |
|
6034 * _.sortBy(characters, getName); |
|
6035 * // => [{ 'name': 'barney', 'age': 36 }, { 'name': 'fred', 'age': 40 }] |
|
6036 */ |
|
6037 function property(key) { |
|
6038 return function(object) { |
|
6039 return object[key]; |
|
6040 }; |
|
6041 } |
10137 } |
6042 |
10138 |
6043 /** |
10139 /** |
6044 * Produces a random number between `min` and `max` (inclusive). If only one |
10140 * Produces a random number between `min` and `max` (inclusive). If only one |
6045 * argument is provided a number between `0` and the given number will be |
10141 * argument is provided a number between `0` and the given number is returned. |
6046 * returned. If `floating` is truey or either `min` or `max` are floats a |
10142 * If `floating` is `true`, or either `min` or `max` are floats, a floating-point |
6047 * floating-point number will be returned instead of an integer. |
10143 * number is returned instead of an integer. |
6048 * |
10144 * |
6049 * @static |
10145 * @static |
6050 * @memberOf _ |
10146 * @memberOf _ |
6051 * @category Utilities |
10147 * @category Number |
6052 * @param {number} [min=0] The minimum possible value. |
10148 * @param {number} [min=0] The minimum possible value. |
6053 * @param {number} [max=1] The maximum possible value. |
10149 * @param {number} [max=1] The maximum possible value. |
6054 * @param {boolean} [floating=false] Specify returning a floating-point number. |
10150 * @param {boolean} [floating] Specify returning a floating-point number. |
6055 * @returns {number} Returns a random number. |
10151 * @returns {number} Returns the random number. |
6056 * @example |
10152 * @example |
6057 * |
10153 * |
6058 * _.random(0, 5); |
10154 * _.random(0, 5); |
6059 * // => an integer between 0 and 5 |
10155 * // => an integer between 0 and 5 |
6060 * |
10156 * |