Рекурсивно вернуть массив объектных и вложенных объектных ключей - PullRequest
0 голосов
/ 04 июня 2019

В настоящее время я изучаю рекурсию и перешел от чисел, строк и массивов к использованию ее на объектах ... Я пытаюсь найти наилучший способ получения объекта в качестве аргумента и сбора ключей. объекта и всех вложенных объектов в массив

Я могу вернуть ключи объекта одного объекта, не используя рекурсию. Поэтому я пытался создать переменную в виде пустого массива, затем выполнить итерацию по объекту с помощью цикла for, а если «i» - это объект, то вставьте ключи объекта в переменную массива и верните ее. Это не сработает, к сожалению.

Хотелось бы следующее:

{lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

Для возврата:

[lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]

Надеюсь, этого достаточно, дайте мне знать, если нет :)

Я попробовал следующее:

function(obj) {
let keysArray = [];
for (let i = 0, i < obj.length, i++)
if (obj[i] === typeOf object) {
keysArray.push(obj[i].keys);
}
return keysArray
}

Ответы [ 4 ]

2 голосов
/ 04 июня 2019

Вы можете написать рекурсивную функцию следующим образом

let obj = {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}};

function getKeys(o) {
  let result = [];
  for (let key in o) {
    result.push(key);
    if(o[key] && typeof o[key] === "object") result.push(...getKeys(o[key]));
  }
  return result;
}

console.log(getKeys(obj));
1 голос
/ 04 июня 2019

Как насчет:

const keys = obj => Object.keys(obj).reduce((acc, key) => {
  acc.push(key);
  return (obj[key] !== null && typeof obj[key] === 'object') // Avoid evaluating null as an object
    ? acc.concat(keys(obj[key])) 
    : acc;
}, []);

Использование:

keys({foo: 1, bar: {foobar: 2}}); // Outputs ['foo', 'bar', 'foobar']
1 голос
/ 04 июня 2019
  • Вам необходимо перебрать объект, используя for...in. Цикл for предназначен для массивов
  • obj[i] === typeOf object неверно. Это должно быть typeof obj[key] === "object".
  • Если вложенное свойство является объектом, вам нужно рекурсивно вызвать функцию и push нажать клавишу keysArray

function getKeys(obj) {
  let keysArray = [];
  
  for (let key in obj) {
    keysArray.push(key);
    
    if (typeof obj[key] === "object")
      keysArray.push(...getKeys(obj[key]))
  }
  return keysArray
}

const input={lamp:2,candle:2,pillow:{big:2,small:4},bathroom:{toilet:1,shower:{shampoo:1,conditioner:2}}}

console.log(getKeys(input))

К вашему сведению: typeof null является «объектом». Таким образом, приведенный выше код выдаст ошибку, если какое-либо из свойств будет нулевым. Итак, Object(obj[k]) === obj[k] можно использовать. Это верно для всех объектов, КРОМЕ для null

Также, если поддерживается flatMap, вы можете сделать что-то вроде этого

const input={lamp:2,candle:2,pillow:{big:2,small:4},bathroom:{toilet:1,shower:{shampoo:1,conditioner:2}}};

const getKeys = obj =>
  Object.keys(obj).flatMap(key => Object(obj[key]) === obj[key] 
                                   ? [key, ...getKeys(obj[key])] 
                                   : key)

console.log(getKeys(input))
0 голосов
/ 05 июня 2019

Очень хороший вариант использования для генераторов. Вот демонстрация -

const data =
  {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

const keys = function* (o = {}) {
  if (Object(o) === o)
    for (const [k, v] of Object.entries(o)) {
      yield k
      yield* keys(v)
    }
}
  
console.log(Array.from(keys(data)))
// [lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]

Другое решение заключается в использовании Array.prototype.flatMap -

const data =
  {lamp: 2, candle: 2, pillow: {big: 2, small: 4}, bathroom: {toilet: 1, shower: {shampoo: 1, conditioner: 2}}}

const keys = (o = {}) =>
  Object(o) === o
    ? Object.entries(o).flatMap(([ k, v ]) =>
        [ k, ...keys(v) ]
      )
    : []
  
console.log(keys(data))
// [lamp, candle, pillow, big, small, bathroom, toilet, shower, shampoo, conditioner]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...