lib/mixin.js
function remove(obj, path, i) {
	i = i || 0

	var key = path[i],
		last = i === path.length - 1

	if (!obj || typeof obj !== 'object') {
		throw new Error('Can\'t remove key ' + key + ' from non-object')
	}

	if (Array.isArray(obj)) {
		if (typeof key !== 'number') {
			obj.forEach(function (each) {
				remove(each, path, i)
			})
		} else if (key >= 0 && key < obj.length) {
			if (last) {
				obj.splice(key, 1)
			} else {
				remove(obj[key], path, i + 1)
			}
		} else {
			throw new Error('Can\'t remove index ' + key + ' from an array with ' + obj.length + ' elements')
		}
	} else {
		if (typeof key !== 'string') {
			throw new Error('Can\'t remove the numeric key ' + key + ' from an object')
		} else if (key in obj) {
			if (last) {
				delete obj[key]
			} else {
				remove(obj[key], path, i + 1)
			}
		} else {
			throw new Error('Can\'t remove key ' + key + ' from the object')
		}
	}
}
function remove(obj, path, i) {
	i = i || 0

	var key = path[i],
		last = i === path.length - 1

	if (!obj || typeof obj !== 'object') {
		throw new Error('Can\'t remove key ' + key + ' from non-object')
	}

	if (Array.isArray(obj)) {
		if (typeof key !== 'number') {
			obj.forEach(function (each) {
				remove(each, path, i)
			})
		} else if (key >= 0 && key < obj.length) {
			if (last) {
				obj.splice(key, 1)
			} else {
				remove(obj[key], path, i + 1)
			}
		} else {
			throw new Error('Can\'t remove index ' + key + ' from an array with ' + obj.length + ' elements')
		}
	} else {
		if (typeof key !== 'string') {
			throw new Error('Can\'t remove the numeric key ' + key + ' from an object')
		} else if (key in obj) {
			if (last) {
				delete obj[key]
			} else {
				remove(obj[key], path, i + 1)
			}
		} else {
			throw new Error('Can\'t remove key ' + key + ' from the object')
		}
	}
}
Remove a path from an object
@param {Object} obj
@param {Array<string|number>} path
@param {number} [i]
@throws {Error}
@private