Created
January 29, 2016 18:26
-
-
Save jt3k/359fbf95588979789760 to your computer and use it in GitHub Desktop.
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
/** | |
* Рекурсивная функция декомпозирующая объект. | |
* Обязательный только первый аргумент остальные нужны только для работы данной функции: TODO спрятать в arguments | |
* @param {Object} obj Приходящий в рекурсию объект(либо другое) | |
* | |
* @param {String} key Ключ по которому пришли | |
* @param {String} curPath Путь к ключу в текстовом виде | |
* @param {Number} deep Глубина рекурсии (глубина пути) | |
* @param {Object} returnObj Объект в который будет набиваться свойствами(см ниже), | |
* а также этот объект будет возвращён из данной функции | |
* @param {Object} upperObj Объект-родитель | |
* | |
* | |
* @return {Object} Объект вида | |
* { | |
* '#/путь/к/ключу/в/текстовом/виде': { | |
* value: 'значение_по_данному_пути', //может быть любым типом данных из объекта | |
* key: 'имя_ключа', | |
* deep: 9, //глубина пути, | |
* curPath: '#/путь/к/ключу/в/текстовом/виде', | |
* upperObj: {ссылка_на_объект_выше} | |
* }, | |
* ... | |
* } | |
*/ | |
function decomposer(obj, key, curPath, deep, returnObj, upperObj) { | |
// текущий путь | |
if (curPath) { | |
curPath += '/' + key; | |
} else { | |
curPath = key || '#'; | |
} | |
// текущая глубина | |
if (deep) { | |
deep += 1; | |
} else { | |
deep = 1; | |
} | |
//входной объект | |
returnObj = returnObj || {}; | |
// рекурсия тут | |
if (_.isObject(obj)) { | |
_.each(obj, function(value, key) { | |
decomposer(value, key, curPath, deep, returnObj, obj); | |
}); | |
} | |
// curPath = curPath.replace(/^#\./,'#'); | |
returnObj[curPath] = { | |
value: obj, | |
key: key, | |
deep: deep, | |
curPath: curPath, | |
upperObj: upperObj | |
}; | |
if (deep === 1) { | |
return returnObj; | |
} | |
} | |
///////////////////////////////////////|||||||||||||||||\\\\\\\\\\\\\\\\\\\\ | |
// пример использования | |
// Допустим нам необходимо делать разные действия с объектом, но мы не знаем где какое свойство лежит и как до него добраться | |
// Вот примерные кейсы которые с этой функцией возможны: | |
// 1) найти все места у которых есть свойство foo и добавить рядом свойство _newProp | |
// 2) найти все свойства со значением 123 и удалить весь объект в котором это свойство есть или любого из их родителей (например 2 родителя вверх или 99) | |
// 3) да в объем то и всё :) но этого достаточно чтобы делать всё что захочется. | |
// см примеры ниже в комментариях. | |
// берём объект без циклических ссылок. | |
var obj = { | |
foo: 123, | |
bar: 'lalala', | |
baz: { | |
fuz: { | |
biz: { | |
foo: 'bar in foo!' | |
} | |
} | |
} | |
}; | |
//декомпозируем объект | |
var decomposedObj = decomposer(obj); | |
var foos = _.filter(decomposedObj, { key: 'foo'}); | |
console.log(foos); // ==> вернёт 2 элемента с которыми можно делать ВСЁ %) ---> см в консоль (и действуй) | |
// ПОЛУЧИТЬ ТОЛЬКО ЗНАЧЕНИЯ СВОЙСТВ: | |
// _.map(foos, function(item){ return item.value}); | |
// ДОБАВИТЬ НОВЫЕ СВОЙСТВА В ОБЪЕКТ: | |
// _.each(foos, function(item){ item.upperObj._newProp = 'lalala';}) | |
// console.log(obj); ==> новые свойства добавлены в объектик. | |
// ДОБАВИТЬ НОВЫЕ СВОЙСВА В ОБЪЕКТ на два уровня выше | |
// // мы делаем .curPath = "#/baz/fuz/biz/foo" ==> "#/baz/fuz" | |
// var newPath = foos[1].curPath.split('/').slice(0, -2).join('/'); | |
// var twoLevelUpObj = decomposedObj[newPath]; | |
// twoLevelUpObj.upperObj._newProp2 = 'YOHOHO'; | |
// // теперь наш obj будет содержать свойство baz.newProp2 = 'YOHOHO' | |
// почти таким способом мы можем сделать delete любому объекту из цепочки родителей. | |
////////////////////////////////// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment