/** * lodash 3.0.0 (Custom Build) * Build: `lodash modern modularize exports="npm" -o ./` * Copyright 2012-2015 The Dojo Foundation * Based on Underscore.js 1.7.0 * Copyright 2009-2015 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ var arrayFilter = require('lodash._arrayfilter'), baseCallback = require('lodash._basecallback'), baseClone = require('lodash._baseclone'), baseFilter = require('lodash._basefilter'), baseIsEqual = require('lodash._baseisequal'), isArray = require('lodash.isarray'), keys = require('lodash.keys'); /** Used for native method references. */ var objectProto = Object.prototype; /** Used to check objects for own properties. */ var hasOwnProperty = objectProto.hasOwnProperty; /** * The base implementation of `_.isMatch` without support for callback * shorthands or `this` binding. * * @private * @param {Object} source The object to inspect. * @param {Array} props The source property names to match. * @param {Array} values The source values to match. * @param {Array} strictCompareFlags Strict comparison flags for source values. * @param {Function} [customizer] The function to customize comparing objects. * @returns {boolean} Returns `true` if `object` is a match, else `false`. */ function baseIsMatch(object, props, values, strictCompareFlags, customizer) { var length = props.length; if (object == null) { return !length; } var index = -1, noCustomizer = !customizer; while (++index < length) { if ((noCustomizer && strictCompareFlags[index]) ? values[index] !== object[props[index]] : !hasOwnProperty.call(object, props[index]) ) { return false; } } index = -1; while (++index < length) { var key = props[index]; if (noCustomizer && strictCompareFlags[index]) { var result = hasOwnProperty.call(object, key); } else { var objValue = object[key], srcValue = values[index]; result = customizer ? customizer(objValue, srcValue, key) : undefined; if (typeof result == 'undefined') { result = baseIsEqual(srcValue, objValue, customizer, true); } } if (!result) { return false; } } return true; } /** * The base implementation of `_.matches` which supports specifying whether * `source` should be cloned. * * @private * @param {Object} source The object of property values to match. * @param {boolean} [isCloned] Specify cloning the source object. * @returns {Function} Returns the new function. */ function baseMatches(source, isCloned) { var props = keys(source), length = props.length; if (length == 1) { var key = props[0], value = source[key]; if (isStrictComparable(value)) { return function(object) { return object != null && value === object[key] && hasOwnProperty.call(object, key); }; } } if (isCloned) { source = baseClone(source, true); } var values = Array(length), strictCompareFlags = Array(length); while (length--) { value = source[props[length]]; values[length] = value; strictCompareFlags[length] = isStrictComparable(value); } return function(object) { return baseIsMatch(object, props, values, strictCompareFlags); }; } /** * Checks if `value` is suitable for strict equality comparisons, i.e. `===`. * * @private * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` if suitable for strict * equality comparisons, else `false`. */ function isStrictComparable(value) { return value === value && (value === 0 ? ((1 / value) > 0) : !isObject(value)); } /** * Iterates over elements of `collection`, returning an array of all elements * `predicate` returns truthy for. The predicate is bound to `thisArg` and * invoked with three arguments; (value, index|key, collection). * * If a property name is provided for `predicate` the created "_.property" * style callback returns the property value of the given element. * * If an object is provided for `predicate` the created "_.matches" style * callback returns `true` for elements that have the properties of the given * object, else `false`. * * @static * @memberOf _ * @alias select * @category Collection * @param {Array|Object|string} collection The collection to iterate over. * @param {Function|Object|string} [predicate=_.identity] The function invoked * per iteration. If a property name or object is provided it is used to * create a "_.property" or "_.matches" style callback respectively. * @param {*} [thisArg] The `this` binding of `predicate`. * @returns {Array} Returns the new filtered array. * @example * * var evens = _.filter([1, 2, 3, 4], function(n) { return n % 2 == 0; }); * // => [2, 4] * * var users = [ * { 'user': 'barney', 'age': 36, 'active': false }, * { 'user': 'fred', 'age': 40, 'active': true } * ]; * * // using the "_.property" callback shorthand * _.pluck(_.filter(users, 'active'), 'user'); * // => ['fred'] * * // using the "_.matches" callback shorthand * _.pluck(_.filter(users, { 'age': 36 }), 'user'); * // => ['barney'] */ function filter(collection, predicate, thisArg) { var func = isArray(collection) ? arrayFilter : baseFilter; predicate = baseCallback(predicate, thisArg, 3); return func(collection, predicate); } /** * Performs a deep comparison between each element in `collection` and the * source object, returning an array of all elements that have equivalent * property values. * * @static * @memberOf _ * @category Collection * @param {Array|Object|string} collection The collection to search. * @param {Object} source The object of property values to match. * @returns {Array} Returns the new filtered array. * @example * * var users = [ * { 'user': 'barney', 'age': 36, 'status': 'busy', 'pets': ['hoppy'] }, * { 'user': 'fred', 'age': 40, 'status': 'busy', 'pets': ['baby puss', 'dino'] } * ]; * * _.pluck(_.where(users, { 'age': 36 }), 'user'); * // => ['barney'] * * _.pluck(_.where(users, { 'pets': ['dino'] }), 'user'); * // => ['fred'] * * _.pluck(_.where(users, { 'status': 'busy' }), 'user'); * // => ['barney', 'fred'] */ function where(collection, source) { return filter(collection, matches(source)); } /** * Checks if `value` is the language type of `Object`. * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) * * **Note:** See the [ES5 spec](https://es5.github.io/#x8) for more details. * * @static * @memberOf _ * @category Lang * @param {*} value The value to check. * @returns {boolean} Returns `true` if `value` is an object, else `false`. * @example * * _.isObject({}); * // => true * * _.isObject([1, 2, 3]); * // => true * * _.isObject(1); * // => false */ function isObject(value) { // Avoid a V8 JIT bug in Chrome 19-20. // See https://code.google.com/p/v8/issues/detail?id=2291 for more details. var type = typeof value; return type == 'function' || (value && type == 'object') || false; } /** * Creates a function which performs a deep comparison between a given object * and `source`, returning `true` if the given object has equivalent property * values, else `false`. * * @static * @memberOf _ * @category Utility * @param {Object} source The object of property values to match. * @returns {Function} Returns the new function. * @example * * var users = [ * { 'user': 'fred', 'age': 40 }, * { 'user': 'barney', 'age': 36 } * ]; * * var matchesAge = _.matches({ 'age': 36 }); * * _.filter(users, matchesAge); * // => [{ 'user': 'barney', 'age': 36 }] * * _.find(users, matchesAge); * // => { 'user': 'barney', 'age': 36 } */ function matches(source) { return baseMatches(source, true); } module.exports = where;