-
Notifications
You must be signed in to change notification settings - Fork 6
/
find-key.js
62 lines (54 loc) · 1.97 KB
/
find-key.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
/**
* @module object-loops/find-key
*/
var isInteger = require('101/is-integer')
var castArrayKey = function (key) {
var num = parseInt(key, 10)
return isNaN(num) ? key : num
}
/**
* Find the key of the the object that passes the test implemented by the callback.
* @function module:object-loops/find-key
* @param {object} [obj] - object to iterate through, not accepted if being used directly on Object.prototype
* @param {findKeyCallback} callback - function to test each value in the object. return truthy to end the loop and return index, falsey otherwise.
* @param {*} [thisArg] - optional. context to bind to callback
* @returns {*} if callback returns true, the loop is ended and the passing `key` is returned (else undefined)
*/
module.exports = findKey
function findKey (obj, callback, thisArg) {
var isArray = Array.isArray(obj)
if (isArray && obj.findIndex) {
/* $lab:coverage:off$ */ // not covered in envs that don't have `findIndex`
var index = obj.findIndex(callback, thisArg)
return ~index ? index : undefined
/* $lab:coverage:on$ */
}
if (typeof obj !== 'object' && typeof obj !== 'function') {
throw new TypeError(obj + ' must be an object')
}
if (typeof callback !== 'function') {
throw new TypeError(callback + ' must be a function')
}
var ret
var keys = Object.keys(obj)
if (isArray) {
keys = Object.keys(obj).map(castArrayKey).filter(isInteger)
}
for (var i = 0; i < keys.length; i++) {
var key = keys[i]
var val = obj[key]
var pass = callback.call(thisArg, val, key, obj)
if (pass) {
return key
}
}
return ret
}
/**
* This callback type is called `findKeyCallback` and is displayed as a global symbol.
* @callback findKeyCallback
* @param {*} val - value for key
* @param {string} key - object key (used in current iteration)
* @param {object} obj - object which values are being iterated
* @returns {boolean} include - return true to break loop and return key, false otherwise
*/