Created
September 30, 2014 18:26
-
-
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).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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