Skip to content

Instantly share code, notes, and snippets.

@PAEz PAEz/object.js
Last active Jan 6, 2016

Embed
What would you like to do?
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

This comment has been minimized.

Copy link

commented Jan 4, 2016

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

@PAEz

This comment has been minimized.

Copy link
Owner Author

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
You can’t perform that action at this time.