Skip to content

Instantly share code, notes, and snippets.

@pluma
Created September 30, 2014 18:26
Show Gist options
  • Save pluma/1e53642eb6fd6f8b8a06 to your computer and use it in GitHub Desktop.
Save pluma/1e53642eb6fd6f8b8a06 to your computer and use it in GitHub Desktop.
Smarter version of `omit` and `pick` that can handle prop paths including wildcards and escaping (with backslash).
var wildcard = typeof Symbol === 'undefined' ? true : Symbol.for('wildcard');
function _tokenize(key) {
var tokens = [];
for (var i = 0; i < key.length; i++) {
var token = '';
if (key[i] === '*' && (i + 1 >= key.length || key[i + 1] === '.')) {
tokens.push(wildcard);
i++;
continue;
}
for (; i < key.length && key[i] !== '.'; i++) {
if (key[i] === '\\') i++;
token += key[i];
}
tokens.push(token);
}
return tokens;
}
function _propkeys(keys, key) {
var propkeys = [];
for (var i = 0; i < keys.length; i++) {
if (keys[i][0] !== key && keys[i][0] !== wildcard) continue;
if (keys[i].length === 1) return true;
propkeys.push(keys[i].slice(1));
}
return propkeys;
}
function _omit(keys, source, obj, noStubs) {
var modified = false;
for (var key in source) {
if (!source.hasOwnProperty(key)) continue;
var propkeys = _propkeys(keys, key);
if (propkeys === wildcard) continue;
var prop = source[key];
if (source[key] && typeof source[key] === 'object') {
prop = Array.isArray(source[key]) ? [] : {};
var propmodified = _omit(propkeys, source[key], prop, noStubs);
if (!propmodified && noStubs) continue;
}
obj[key] = prop;
modified = true;
}
return modified;
}
function _pick(keys, source, obj, noStubs) {
var modified = false;
for (var key in source) {
if (!source.hasOwnProperty(key)) continue;
var propkeys = _propkeys(keys, key);
if (propkeys.length === 0) continue;
var prop = source[key];
if (propkeys !== wildcard) {
if (!source[key] || typeof source[key] !== 'object') continue;
prop = Array.isArray(source[key]) ? [] : {};
var propmodified = _pick(propkeys, source[key], prop, noStubs);
if (!propmodified && noStubs) continue;
}
obj[key] = prop;
modified = true;
}
return modified;
}
function omit(keys, source, noStubs) {
var _keys = Array.isArray(keys) ? keys : [keys];
var obj = Array.isArray(source) ? [] : {};
_omit(_keys.map(_tokenize), source, obj, noStubs);
return obj;
}
function pick(keys, source, noStubs) {
var _keys = Array.isArray(keys) ? keys : [keys];
var obj = Array.isArray(source) ? [] : {};
_pick(_keys.map(_tokenize), source, obj, noStubs);
return obj;
}
exports.omit = omit;
exports.pick = pick;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment