поиск неопределенного или нулевого значения из объекта внутри объекта - PullRequest
0 голосов
/ 25 февраля 2019

Я хотел бы нажимать клавиши внутри массива, если он найден неопределенным или нулевым

const obj = {
  name:'ab',
  edu:'av',
  degres:{
    a1:'',
    b1:'1'
  },
  platform:undefined
 }

Я хочу вывод типа

  `['a1','platform']`

, поскольку значения для a1 и платформы были нулевыми и неопределенными

я пробовал это решение, но оно не работает

 function iterater(obj){
  let blankValues = [];
  Object.keys(obj).map((key) => {
      if (obj.hasOwnProperty(key) && (typeof obj[key] === "object")) {
        iterater(obj[key])
      } else {
          if (typeof obj[key] === "undefined" || obj[key] === ''){
            blankValues.push(key);
         }
      }
    })
  return blankValues;

}

но это как-то только возвращает ['platform'], но ожидаемый результат должен быть ['platform', 'a1'], я думаю, что при запуске итератора (obj [ключ]) значение массива (blankValues) становится пустым, поскольку оно не сохраняется, но, пожалуйста, помогите мне с соответствующей логикой и структурой

Ответы [ 5 ]

0 голосов
/ 25 февраля 2019

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

const
    getFalsy = o => Object.keys(o).reduce((r, k) => {
        if (!o[k]) return [...r, k];
        if (typeof o[k] === 'object') return [...r, ...getFalsy(o[k])];
        return r;
    }, []),
    object = { name: 'ab', edu: 'av', degres: { a1: '', b1: '1' }, platform: undefined };

console.log(getFalsy(object));
0 голосов
/ 25 февраля 2019

Вы должны отправить результат, возвращаемый рекурсивным вызовом в ваш массив.Изменение:

iterater(obj[key])

для:

blankValues.push(...iterater(obj[key]))

const obj = {
  name: 'ab',
  edu: 'av',
  degres: {
    a1: '',
    b1: '1'
  },
  platform: undefined
}

 function iterater(obj){
  let blankValues = [];
  Object.keys(obj).map((key) => {
      if (obj.hasOwnProperty(key) && (typeof obj[key] === "object")) {
        blankValues.push(...iterater(obj[key]))
      } else {
          if (typeof obj[key] === "undefined" || obj[key] === ''){
            blankValues.push(key);
         }
      }
    })
  return blankValues;

}

console.log(iterater(obj));

Вот еще один способ сделать это, используя Object.entries(), Object.keys(), Array.reduce(), Array.flat() и Array.isArray().Эта реализация работает и для массивов.

const obj = {
  name:'ab',
  edu:'av',
  something: [{ a: 1 }, { a: '' }],
  degres:{
    a1:'',
    b1:'1'
  },
  platform:undefined
};

function getEmptyProps(obj) {
  if (!Object.keys(obj).length) { return []; }
  return Object.entries(obj).reduce((acc, [key, val]) => {
    if (val === undefined || val === null || val.toString().trim() === '') {
      acc.push(key);
    } else if (Array.isArray(val)) {
      acc.push(val.map(getEmptyProps).flat());
    } else if (typeof val === 'object') {
      acc.push(getEmptyProps(val));
    }
    return acc.flat();
  }, []);
}

console.log(getEmptyProps(obj))
0 голосов
/ 25 февраля 2019

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

Также обратите внимание, что, как указано в @ ziggy wiggy комментарии, ваша логика потерпит неудачу, когда встретится значение null, так как typeof obj[key] === "object" будет true.Вам также нужна определенная проверка нуля.

const obj = {
  name: 'ab',
  edu: 'av',
  degres: {
    a1: '',
    b1: '1'
  },
  platform: undefined,
  foo: null
}

function iterater(obj, arr) {
  arr = arr || [];
  Object.keys(obj).map((key) => {
    if (obj.hasOwnProperty(key) && (typeof obj[key] === "object") && obj[key] !== null) {
      iterater(obj[key], arr)
    } else {
      if (typeof obj[key] === "undefined" || obj[key] === null || obj[key].trim() === '') {
        arr.push(key);
      }
    }
  })
  return arr;
}

console.log(iterater(obj));

Обратите внимание, что я также добавил вызов trim() для проверки пустой строки.Ваша предыдущая логика будет принимать строки, заполненные пробелами, в качестве допустимых значений.

0 голосов
/ 25 февраля 2019

Вам нужно использовать результат рекурсивного вызова.Например, добавьте его обратно к blankValues вот так blankValues.push(...iterater(obj[key]))

const obj = {
  name:'ab',
  edu:'av',
  degres:{
    a1:'',
    b1:'1'
  },
  platform:undefined
 }

 function iterater(obj){
  let blankValues = [];
  Object.keys(obj).map((key) => {
      if (obj.hasOwnProperty(key) && (typeof obj[key] === "object")) {
        blankValues.push(...iterater(obj[key]))
      } else {
          if (typeof obj[key] === "undefined" || obj[key] === ''){
            blankValues.push(key);
         }
      }
    })
  return blankValues;

}

console.log(iterater(obj))
0 голосов
/ 25 февраля 2019

Как вы сказали сами, при вызове iterater(obj[key]) он устанавливает новый локальный blankValues и помещает в него значения.Поэтому я думаю, что вы должны поставить blankValues вне функции.И тогда вам не нужно возвращать его (или вы можете, если хотите, чтобы оно возвращалось).

Или вы можете передать blankValues в качестве параметра iterater как в основном вызове, так и в"внутренний" звонок

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...