UNPKG

9.23 kBJavaScriptView Raw
1/**
2 * lodash 4.1.1 (Custom Build) <https://lodash.com/>
3 * Build: `lodash modularize exports="npm" -o ./`
4 * Copyright 2012-2016 The Dojo Foundation <http://dojofoundation.org/>
5 * Based on Underscore.js 1.8.3 <http://underscorejs.org/LICENSE>
6 * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
7 * Available under MIT license <https://lodash.com/license>
8 */
9var baseIsEqual = require('lodash._baseisequal'),
10 baseIsMatch = require('lodash._baseismatch'),
11 basePullAt = require('lodash._basepullat'),
12 get = require('lodash.get'),
13 hasIn = require('lodash.hasin'),
14 toPairs = require('lodash.topairs'),
15 toString = require('lodash.tostring');
16
17/** Used to compose bitmasks for comparison styles. */
18var UNORDERED_COMPARE_FLAG = 1,
19 PARTIAL_COMPARE_FLAG = 2;
20
21/** Used to match property names within property paths. */
22var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
23 reIsPlainProp = /^\w*$/,
24 rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]/g;
25
26/** Used to match backslashes in property paths. */
27var reEscapeChar = /\\(\\)?/g;
28
29/**
30 * The base implementation of `_.get` without support for default values.
31 *
32 * @private
33 * @param {Object} object The object to query.
34 * @param {Array|string} path The path of the property to get.
35 * @returns {*} Returns the resolved value.
36 */
37function baseGet(object, path) {
38 path = isKey(path, object) ? [path + ''] : baseToPath(path);
39
40 var index = 0,
41 length = path.length;
42
43 while (object != null && index < length) {
44 object = object[path[index++]];
45 }
46 return (index && index == length) ? object : undefined;
47}
48
49/**
50 * The base implementation of `_.iteratee`.
51 *
52 * @private
53 * @param {*} [value=_.identity] The value to convert to an iteratee.
54 * @returns {Function} Returns the iteratee.
55 */
56function baseIteratee(value) {
57 var type = typeof value;
58 if (type == 'function') {
59 return value;
60 }
61 if (value == null) {
62 return identity;
63 }
64 if (type == 'object') {
65 return isArray(value)
66 ? baseMatchesProperty(value[0], value[1])
67 : baseMatches(value);
68 }
69 return property(value);
70}
71
72/**
73 * The base implementation of `_.matches` which doesn't clone `source`.
74 *
75 * @private
76 * @param {Object} source The object of property values to match.
77 * @returns {Function} Returns the new function.
78 */
79function baseMatches(source) {
80 var matchData = getMatchData(source);
81 if (matchData.length == 1 && matchData[0][2]) {
82 var key = matchData[0][0],
83 value = matchData[0][1];
84
85 return function(object) {
86 if (object == null) {
87 return false;
88 }
89 return object[key] === value &&
90 (value !== undefined || (key in Object(object)));
91 };
92 }
93 return function(object) {
94 return object === source || baseIsMatch(object, source, matchData);
95 };
96}
97
98/**
99 * The base implementation of `_.matchesProperty` which doesn't clone `srcValue`.
100 *
101 * @private
102 * @param {string} path The path of the property to get.
103 * @param {*} srcValue The value to match.
104 * @returns {Function} Returns the new function.
105 */
106function baseMatchesProperty(path, srcValue) {
107 return function(object) {
108 var objValue = get(object, path);
109 return (objValue === undefined && objValue === srcValue)
110 ? hasIn(object, path)
111 : baseIsEqual(srcValue, objValue, undefined, UNORDERED_COMPARE_FLAG | PARTIAL_COMPARE_FLAG);
112 };
113}
114
115/**
116 * The base implementation of `_.property` without support for deep paths.
117 *
118 * @private
119 * @param {string} key The key of the property to get.
120 * @returns {Function} Returns the new function.
121 */
122function baseProperty(key) {
123 return function(object) {
124 return object == null ? undefined : object[key];
125 };
126}
127
128/**
129 * A specialized version of `baseProperty` which supports deep paths.
130 *
131 * @private
132 * @param {Array|string} path The path of the property to get.
133 * @returns {Function} Returns the new function.
134 */
135function basePropertyDeep(path) {
136 return function(object) {
137 return baseGet(object, path);
138 };
139}
140
141/**
142 * The base implementation of `_.toPath` which only converts `value` to a
143 * path if it's not one.
144 *
145 * @private
146 * @param {*} value The value to process.
147 * @returns {Array} Returns the property path array.
148 */
149function baseToPath(value) {
150 return isArray(value) ? value : stringToPath(value);
151}
152
153/**
154 * Gets the property names, values, and compare flags of `object`.
155 *
156 * @private
157 * @param {Object} object The object to query.
158 * @returns {Array} Returns the match data of `object`.
159 */
160function getMatchData(object) {
161 var result = toPairs(object),
162 length = result.length;
163
164 while (length--) {
165 result[length][2] = isStrictComparable(result[length][1]);
166 }
167 return result;
168}
169
170/**
171 * Checks if `value` is a property name and not a property path.
172 *
173 * @private
174 * @param {*} value The value to check.
175 * @param {Object} [object] The object to query keys on.
176 * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
177 */
178function isKey(value, object) {
179 if (typeof value == 'number') {
180 return true;
181 }
182 return !isArray(value) &&
183 (reIsPlainProp.test(value) || !reIsDeepProp.test(value) ||
184 (object != null && value in Object(object)));
185}
186
187/**
188 * Checks if `value` is suitable for strict equality comparisons, i.e. `===`.
189 *
190 * @private
191 * @param {*} value The value to check.
192 * @returns {boolean} Returns `true` if `value` if suitable for strict
193 * equality comparisons, else `false`.
194 */
195function isStrictComparable(value) {
196 return value === value && !isObject(value);
197}
198
199/**
200 * Converts `string` to a property path array.
201 *
202 * @private
203 * @param {string} string The string to convert.
204 * @returns {Array} Returns the property path array.
205 */
206function stringToPath(string) {
207 var result = [];
208 toString(string).replace(rePropName, function(match, number, quote, string) {
209 result.push(quote ? string.replace(reEscapeChar, '$1') : (number || match));
210 });
211 return result;
212}
213
214/**
215 * Removes all elements from `array` that `predicate` returns truthy for
216 * and returns an array of the removed elements. The predicate is invoked with
217 * three arguments: (value, index, array).
218 *
219 * **Note:** Unlike `_.filter`, this method mutates `array`.
220 *
221 * @static
222 * @memberOf _
223 * @category Array
224 * @param {Array} array The array to modify.
225 * @param {Function|Object|string} [predicate=_.identity] The function invoked per iteration.
226 * @returns {Array} Returns the new array of removed elements.
227 * @example
228 *
229 * var array = [1, 2, 3, 4];
230 * var evens = _.remove(array, function(n) {
231 * return n % 2 == 0;
232 * });
233 *
234 * console.log(array);
235 * // => [1, 3]
236 *
237 * console.log(evens);
238 * // => [2, 4]
239 */
240function remove(array, predicate) {
241 var result = [];
242 if (!(array && array.length)) {
243 return result;
244 }
245 var index = -1,
246 indexes = [],
247 length = array.length;
248
249 predicate = baseIteratee(predicate, 3);
250 while (++index < length) {
251 var value = array[index];
252 if (predicate(value, index, array)) {
253 result.push(value);
254 indexes.push(index);
255 }
256 }
257 basePullAt(array, indexes);
258 return result;
259}
260
261/**
262 * Checks if `value` is classified as an `Array` object.
263 *
264 * @static
265 * @memberOf _
266 * @type Function
267 * @category Lang
268 * @param {*} value The value to check.
269 * @returns {boolean} Returns `true` if `value` is correctly classified, else `false`.
270 * @example
271 *
272 * _.isArray([1, 2, 3]);
273 * // => true
274 *
275 * _.isArray(document.body.children);
276 * // => false
277 *
278 * _.isArray('abc');
279 * // => false
280 *
281 * _.isArray(_.noop);
282 * // => false
283 */
284var isArray = Array.isArray;
285
286/**
287 * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.
288 * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
289 *
290 * @static
291 * @memberOf _
292 * @category Lang
293 * @param {*} value The value to check.
294 * @returns {boolean} Returns `true` if `value` is an object, else `false`.
295 * @example
296 *
297 * _.isObject({});
298 * // => true
299 *
300 * _.isObject([1, 2, 3]);
301 * // => true
302 *
303 * _.isObject(_.noop);
304 * // => true
305 *
306 * _.isObject(null);
307 * // => false
308 */
309function isObject(value) {
310 var type = typeof value;
311 return !!value && (type == 'object' || type == 'function');
312}
313
314/**
315 * This method returns the first argument given to it.
316 *
317 * @static
318 * @memberOf _
319 * @category Util
320 * @param {*} value Any value.
321 * @returns {*} Returns `value`.
322 * @example
323 *
324 * var object = { 'user': 'fred' };
325 *
326 * _.identity(object) === object;
327 * // => true
328 */
329function identity(value) {
330 return value;
331}
332
333/**
334 * Creates a function that returns the value at `path` of a given object.
335 *
336 * @static
337 * @memberOf _
338 * @category Util
339 * @param {Array|string} path The path of the property to get.
340 * @returns {Function} Returns the new function.
341 * @example
342 *
343 * var objects = [
344 * { 'a': { 'b': { 'c': 2 } } },
345 * { 'a': { 'b': { 'c': 1 } } }
346 * ];
347 *
348 * _.map(objects, _.property('a.b.c'));
349 * // => [2, 1]
350 *
351 * _.map(_.sortBy(objects, _.property(['a', 'b', 'c'])), 'a.b.c');
352 * // => [1, 2]
353 */
354function property(path) {
355 return isKey(path) ? baseProperty(path) : basePropertyDeep(path);
356}
357
358module.exports = remove;