There appears to be an idiomatic use of lodash pickBy
utility function whereby instead of supplying a boolean predicate function as the second argument, an object literal is supplied instead. E.g. https://stackoverflow.com/a/51744183/274677
Animals = [{Name: 'Dog', Id: 0},
{Name: 'Cat', Id: 1},
{Name: 'Mouse', Id: 2},
{Name: 'Horse', Id: 3},
{Name: 'Pig', Id: 3}]
Indexes = _.keys(_.pickBy(Animals, {Id: 3}))
output:
Indexes = ["3", "4"]
This use is undocumented in lodash: https://lodash.com/docs/4.17.15#pickBy
What is the origin of this idiom and why does it work?
Looking at the compiled lodash's code we can see that the pickBy
looks like that:
function pickBy(object, predicate) {
if (object == null) {
return {};
}
var props = arrayMap(getAllKeysIn(object), function(prop) {
return [prop];
});
predicate = getIteratee(predicate);
return basePickBy(object, props, function(value, path) {
return predicate(value, path[0]);
});
}
predicate
(in our example {Id: 3}
) is passed to the getIteratee
function which looks like that:
function getIteratee() {
var result = lodash.iteratee || iteratee;
result = result === iteratee ? baseIteratee : result;
return arguments.length ? result(arguments[0], arguments[1]) : result;
}
Now, looking at the iteratee
:
function iteratee(func) {
return baseIteratee(typeof func == 'function' ? func : baseClone(func, CLONE_DEEP_FLAG));
}
And baseIteratee
:
function baseIteratee(value) {
// Don't store the `typeof` result in a variable to avoid a JIT bug in Safari 9.
// See https://bugs.webkit.org/show_bug.cgi?id=156034 for more details.
if (typeof value == 'function') {
return value;
}
if (value == null) {
return identity;
}
if (typeof value == 'object') {
return isArray(value)
? baseMatchesProperty(value[0], value[1])
: baseMatches(value);
}
return property(value);
}
We know that our argument is an object, but not an array, so few more functions deeper we can find the actual function that is returned:
function getMatchData(object) {
var result = keys(object),
length = result.length;
while (length--) {
var key = result[length],
value = object[key];
result[length] = [key, value, isStrictComparable(value)];
}
return result;
}
which just goes through an array and checks if the value is equal
I have no idea, sorry