Как из всех примитивных значений во вложенных объектах получить одно случайное?

Подскажите пожалуйста, как я могу получить случайное конечное свойство, находящееся во вложенном объекте?

Пример:

const obj = {
    obj_in: {
        obj_end: 'Hello';
        obj_end2: 'Hi';
    },
    obj_in2: {
        obj_end3: 'Goodbye';
        obj_end4: 'Bye';
    }
};

const random_obj = Math.floor(Math.random()*Object.keys(obj.length)); // Получаем случайный индекс, к которому потом можеш обратиться.

// Как я могу получить случайное конечное свойство? Например: obj_end3. 

Ответы (2 шт):

Автор решения: Konstantin Modin

Можно сначала при помощи рекурсивной функции получить все конечные значения, затем из массива выбрать случайный элемент. Примерно так:

const obj = {
    obj_in: {
        obj_end: 'Hello',
        obj_end2: 'Hi',
    },
    obj_in2: {
        obj_end3: 'Goodbye',
        obj_end4: 'Bye',
        some: {
          deep: {
            nested: 'stuff'
          }
        }
    }    
};

const flatten=(o)=>[].concat(...Object.keys(o).map(k => typeof o[k]==='object' ? flatten(o[k]) : o[k]));
const values = flatten(obj);
console.log(values)

for (let i = 0; i < 10 ; i++ ){
  console.log('Random:', values[Math.floor(Math.random()*values.length)])
}
   

→ Ссылка
Автор решения: yar85

const obj = {
  obj_in: {
    obj_end: 'Hello',
    obj_end2: 'Hi',
  },
  obj_in2: {
    obj_end3: 'Goodbye',
    obj_end4: 'Bye',
    obj_in2_in: {
      obj_end5: 'foo',
      obj_in2_in_in: {
        obj_end6: 'bar'
      }
    },
    obj_in2_in2: {
      obj_end7: 'baz'
    }
  }
};

const values = getAllPrimitiveValues(obj);
const randomValue = () => values[Math.floor(Math.random() * values.length)];

console.log('Случайные значения:', ...Array.from({ length: 7 }, randomValue));

function getAllPrimitiveValues(x) { // эти 5 строк вместо lodash весом 73КБ (24КБ gzip)
  return ((typeof x !== 'object') ? [x] : [
    ...Object.values(x).map(getAllPrimitiveValues)
  ]).flat(Infinity);
}


Array.prototype.flat (MDN)

→ Ссылка