Skip to content

Instantly share code, notes, and snippets.

@vldvel
Created April 20, 2018 07:03
Show Gist options
  • Save vldvel/23a34bc8c2b347876cf6d27335c963ad to your computer and use it in GitHub Desktop.
Save vldvel/23a34bc8c2b347876cf6d27335c963ad to your computer and use it in GitHub Desktop.
find lodash
/**
* Main function
*/
function find(collection, predicate, fromIndex) {
let iteratee
const iterable = Object(collection)
if (!isArrayLike(collection)) {
collection = keys(collection)
iteratee = (key) => predicate(iterable[key], key, iterable)
}
const index = findIndex(collection, predicate, fromIndex)
return index > -1 ? iterable[iteratee ? collection[index] : index] : undefined
}
/**
* Dependencies
*/
function isArrayLike(value) {
return value != null && typeof value != 'function' && isLength(value.length)
}
function keys(object) {
return isArrayLike(object)
? arrayLikeKeys(object)
: Object.keys(Object(object))
}
function findIndex(array, predicate, fromIndex, fromRight) {
const { length } = array
let index = fromIndex + (fromRight ? 1 : -1)
while ((fromRight ? index-- : ++index < length)) {
if (predicate(array[index], index, array)) {
return index
}
}
return -1
}
/**
* Dependencies of dependencies
*/
const MAX_SAFE_INTEGER = 9007199254740991
function isLength(value) {
return typeof value == 'number' &&
value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER
}
function arrayLikeKeys(value, inherited) {
const isArr = Array.isArray(value)
const isArg = !isArr && isArguments(value)
const isBuff = !isArr && !isArg && isBuffer(value)
const isType = !isArr && !isArg && !isBuff && isTypedArray(value)
const skipIndexes = isArr || isArg || isBuff || isType
const length = value.length
const result = new Array(skipIndexes ? length : 0)
let index = skipIndexes ? -1 : length
while (++index < length) {
result[index] = `${index}`
}
for (const key in value) {
if ((inherited || hasOwnProperty.call(value, key)) &&
!(skipIndexes && (
// Safari 9 has enumerable `arguments.length` in strict mode.
(key == 'length' ||
// Node.js 0.10 has enumerable non-index properties on buffers.
(isBuff && (key == 'offset' || key == 'parent')) ||
// PhantomJS 2 has enumerable non-index properties on typed arrays.
(isType && (key == 'buffer' || key == 'byteLength' || key == 'byteOffset')) || // Skip index properties.
isIndex(key, length))
))) {
result.push(key)
}
}
return result
}
/**
* Dependencies of dependencies of dependencies
*/
function isArguments(value) {
return isObjectLike(value) && getTag(value) == '[object Arguments]'
}
const isBuffer = nativeIsBuffer || (() => false)
function isIndex(value, length) {
const type = typeof value
length = length == null ? MAX_SAFE_INTEGER : length
return !!length &&
(type == 'number' ||
(type != 'symbol' && reIsUint.test(value))) &&
(value > -1 && value % 1 == 0 && value < length)
}
const isTypedArray = nodeIsTypedArray
? (value) => nodeIsTypedArray(value)
: (value) => isObjectLike(value) && reTypedTag.test(getTag(value))
/**
* Dependencies of dependencies of dependencies of dep...
* and list is going on...
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment