Pick a Subset of Object Keys
Picking a whitelist of fields from an object is a daily chore for API responses, form submissions, and analytics events. This snippet covers the canonical Object.fromEntries filter, a typed-friendly variant that drops missing keys, and a generic helper that picks by predicate. Stop hand-rolling it for every endpoint and reach for the version that fits your data.
245 views
2
function pick(obj, keys) {
return Object.fromEntries(
Object.entries(obj).filter(([k]) => keys.includes(k))
);
}
const user = { id: 1, name: 'Ada', email: '[email protected]', secret: 'hush' };
console.log(pick(user, ['id', 'name']));
// { id: 1, name: 'Ada' }The cleanest one-liner walks the object's own enumerable entries and keeps only the pairs whose key is in the whitelist. Object.fromEntries then rebuilds an object from the surviving [key, value] tuples. This runs in O(n + m) where n is the entry count and m is the keys list, and it never touches inherited properties because Object.entries only sees own enumerable keys. Use this when you trust the whitelist source and don't care that absent keys silently disappear from the result.
function pickStrict(obj, keys) {
const allowed = new Set(keys);
const result = {};
for (const key of allowed) {
if (key in obj) result[key] = obj[key];
}
return result;
}
const record = { id: 1, name: 'Ada' };
console.log(pickStrict(record, ['id', 'name', 'email']));
// { id: 1, name: 'Ada' }
console.log(pickStrict(record, ['id']));
// { id: 1 }Switching from keys.includes to a Set lookup turns each key check from O(m) into O(1), which matters once the whitelist gets long. Iterating the keys list (instead of the object) also lets the result key order match the caller's intent rather than the object's insertion order. The key in obj check skips keys that aren't on the source so the output stays clean of undefined values. Reach for this version when the whitelist comes from config and may grow over time.
function pickBy(obj, predicate) {
const result = {};
for (const [key, value] of Object.entries(obj)) {
if (predicate(value, key)) result[key] = value;
}
return result;
}
const payload = { id: 1, name: 'Ada', email: '', age: null, active: true };
// Drop empty / null fields before sending to an API
console.log(pickBy(payload, (v) => v !== '' && v !== null));
// { id: 1, name: 'Ada', active: true }
// Keep only keys starting with 'a'
console.log(pickBy(payload, (_, k) => k.startsWith('a')));
// { age: null, active: true }A predicate-driven pickBy generalises the helper from a fixed whitelist to any value or key rule, which covers "drop empty fields before PATCH", "keep only truthy values", or "keep keys matching a prefix". The predicate receives both value and key so caller code stays declarative. This still runs in O(n) and never mutates the source, so it's safe to chain into JSON.stringify or another transform. Use the simpler pick for whitelisting and pickBy for value-shaped filters.
