Skip to content

Instantly share code, notes, and snippets.

@PAEz
Last active January 6, 2016 18:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save PAEz/57a99677e65f7d39a7a9 to your computer and use it in GitHub Desktop.
Save PAEz/57a99677e65f7d39a7a9 to your computer and use it in GitHub Desktop.
Object iterate, toPath, map
function objectIterate(obj, callback, stack, cache) {
cache = cache || [];
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var value = obj[property];
if (typeof value == "object" && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
return;
}
cache.push(value);
objectIterate(value, callback, (stack ? stack + '.' : '') + property, cache);
} else {
callback((stack ? stack + '.' : '') + property, obj, property);
}
}
}
}
// Nearly there now
function objectIterate(obj, callback, arrays, objects, stack, cache, inArray) {
if (cache === undefined) {
cache = [];
}
if (stack === undefined) {
stack = '';
}
for (var property in obj) {
if (obj.hasOwnProperty(property)) {
var value = obj[property];
if (typeof value == "object" && value !== null) {
if (cache.indexOf(value) !== -1) {
// Circular reference found, discard key
continue;
}
cache.push(value);
var isArray = Array.isArray(value);
if (objects) {
var nextStack = '';
if (inArray)
nextStack = '[' + property + ']';
else if (!stack.length)
nextStack = property;
else
nextStack += '.' + property;
callback(stack + nextStack, obj, property);
}
if (!(!arrays && isArray)) {
var newStack = '';
if (!stack.length)
newStack = property;
else
newStack = (inArray ? '[' + property + ']' : '.' + property);
objectIterate(value, callback, arrays, objects, stack + newStack, cache, isArray);
}
} else {
// property
var nextStack = '';
if (inArray)
nextStack = '[' + property + ']';
else if (!stack.length)
nextStack = property;
else
nextStack += '.' + property;
callback(stack + nextStack, obj, property);
}
}
}
}
function objectToPath(obj, prop, callback, create) { // Rename to objectValue later
// small change to allow paths like 'a[0].c.d[3][4].e' which is the same as a.0.c.d.3.4.e
prop=prop.replace(/^\[([0-9]*)\]/g,'$1').replace(/\[([0-9]*)\]/g,'.$1'); // I still suck at regexp's ;P
var keys = prop.split('.'),
value, key;
for (var i = 0, end = keys.length - 1; i < end; i++) {
key = keys[i];
value = obj[key];
if (typeof value == "object" && value !== null) {
obj = value;
} else {
if (!create) {
if(callback!==undefined)callback();
return;
}
obj[key] = {};
obj = obj[key];
}
}
key = keys[i];
value = obj[key];
if (obj.hasOwnProperty(key)){
if (callback !== undefined) callback(value, obj, key);
return value;
}
else {
if (!create) {
callback();
return;
}
obj[key] = null;
if (callback !== undefined) callback(obj[key], obj, key);
return null;
}
}
function objectMap(map, source, dest) {
dest = dest || {};
objectIterate(map, function(path, obj, property) {
objectToPath(dest, path, function(destValue, destObject, destProp) {
objectToPath(source, obj[property], function(sourceValue, sourceObject) {
if(sourceObject)destObject[destProp] = sourceValue;
})
}, true)
});
return dest;
}
var _sourceValues = {
a: {
one: 1
},
b: {
c: {
two: 2
}
},
three: 3
};
var _map = {
one: 'a.one',
two: 'b.c.two',
three: 'three',
z: {
x: {
one: 'a.one.b'
}
}
};
console.log(objectMap(_map, _sourceValues));
@chiedo
Copy link

chiedo commented Jan 4, 2016

Hey!
Could you add some JSDOC style function comments? That will help me as I go to implement these. :)

@PAEz
Copy link
Author

PAEz commented Jan 5, 2016

Sorry, only just noticed your comment.
I wouldnt mind doing, you got me interested in JSDOC.

Gonna be a bit. You made me decide I want to make the last object iterate I ever make and so I keep changing it.
Nearly there now tho, just wanna use that type checking you used and thinking of going the complete hog and checking for property on functions, regex, that sort of thing....if Im going complete, I may as well try to be complete ;P.
Even does normal looking paths now like a[9][1] sorta stuff. Ummmmd about using your syntax coz I quite like it, but decided on the usual, just coz its the usual.
Loving your stuff by the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment