从对象内部的对象中找到未定义或空值

时间:2019-02-25 11:13:04

标签: javascript jquery arrays reactjs object

如果未定义或为空,我想将键推入数组

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

我想要类似

的输出
  `['a1','platform']`

因为a1和platform的值为空且未定义

我对这个解决方案很陌生,但是它不起作用

 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'],我认为在运行iterater(obj [key])时,数组的值(blankValues)变得空白,因为它不能保留它,但是请以适当的逻辑和结构帮助我

5 个答案:

答案 0 :(得分:4)

问题是因为您在递归循环的每次迭代中都将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()调用来测试空字符串。您以前的逻辑将接受用空格填充的字符串作为有效值。

答案 1 :(得分:0)

正如您自己说的那样,当您调用iterater(obj[key])时,它将设置一个新的本地blankValues并将值放入其中。因此,我认为您应该将blankValues放在函数之外。 然后,您不必返回它(或者,如果您希望将其作为返回值也可以)。

或者您可以在主调用和“内部”调用中将blankValues作为iterater的参数传递

答案 2 :(得分:0)

您需要使用递归调用的结果。例如,像这样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))

答案 3 :(得分:0)

必须将递归调用返回的结果推送到数组中。 更改:

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))

答案 4 :(得分:0)

您可以检查伪造的密钥并返回密钥,如果属性是对象,则检查该对象。

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));