Как искать значение во вложенных объектах?
Возьмем такой объект, для примера:
{a: {b: {message: 1, d: {message: 2}}}};
Как найти все message без рекурсии или с ее хвостовой оптимизацией.
Объекты могут быть очень большими, больше, чем в примере, есть риск "словить" переполнение стека. А оптимизацию хвостовой рекурсии корректно имплементировать не смог.
Update 1:
function objectScale() {
let scaled = {message: 'test'};
for (let i = 0; i < 1e6; i++) {
scaled = {scaled, message: '1'};
}
return scaled;
}
const object = objectScale();
Как найти все message в object? Скажем, добавить их в массив?
Update 2:
Пример результата:
[1, 1, 1, 1, 1, 1] (получен от array.push(message), где message - 1)
Ответы (1 шт):
Объект можно рассматривать в качестве графа: корнем является сам объект, а ветвями - свойства.
Таким образом задача сводится к обходу графа в глубину либо в ширину.
Для этого достаточно хранить все доступные ветки в массиве и в цикле постепенно исключать их, добавляя при этом дочерние ветки.
Для более удобной работы можно воспользоваться методом Object.entries, позволяющий получить список ключей и их значений.
function objectScale() {
let scaled = {
message: 'test'
};
for (let i = 0; i < 5; i++) {
scaled = {
scaled,
message: 'test' + (i + 1)
};
}
return scaled;
}
const object = objectScale();
function find(o, findkey) {
var entries = Object.entries(o); // получаем дочерние узлы
var result = [];
while (entries.length) { // пока есть непроверенные узлы
var [key, val] = entries.pop(); // берем один узел
if (key == findkey) result.push(val); // если ключ соответствует искомому - добавляем результат
// если значение является объектом
if (val != null && typeof val == 'object') entries.push(...Object.entries(val)); // добавляем его дочерние узлы в список непроверенных
}
return result;
}
console.log(find(object, 'message'))