遍历复杂的反应状态以删除所有空字符串

时间:2020-09-09 13:19:28

标签: javascript reactjs

我有一个复杂的反应状态,其结构如下:

{
   a: [
        {
           a: ['b','',]
         }
       ],
    b: {
         a: ['b',''],
         b: {c:'e',f:''}
       },
     c: 'd',
     e: '',
     f: ['g',''],
     date: new Date()
}

如您所见,对象中可能有很多空字符串。在将其提交给后端之前,我想遍历状态对象并删除所有空值。因此,我首先需要深度克隆状态,以免与我的应用程序状态发生冲突,这可以通过以下方式完成:

clone = JSON.parse(JSON.stringify(state))

但是如何遍历clone并删除所有空字符串?

2 个答案:

答案 0 :(得分:2)

您可以将replacer函数传递到您的JSON.stringify()方法中。从替换函数返回undefined会删除键值对,因此遇到空字符串时可以返回undefined。同样,遇到数组时,可以对其进行过滤以仅包含非空字符串的值。

请参见以下示例:

const state = {
  a: [{
    a: ['b', '', ]
  }],
  b: {
    a: ['b', ''],
    b: {
      c: 'e',
      f: ''
    }
  },
  c: 'd',
  e: '',
  f: ['g', ''],
  h: {},
  date: new Date()
};

const clone = JSON.parse(JSON.stringify(state, (key, value) => {
  if (typeof value === 'string' && value === "" || Object(value) === value && Object.keys(value).length === 0) {
    return undefined;
  } else if(Array.isArray(value)) {
    return value.filter(val => val !== "");
  }
  return value;
}));
console.log(clone);

答案 1 :(得分:1)

您还可以创建一个具有专用功能的新对象,该功能以递归方式删除空字符串。像这样:

const removeEmpties = (obj) => 
  Array .isArray (obj)
    ? obj .filter (x => x !== '') .map (removeEmpties)
  : Object (obj) === obj
    ? Object .fromEntries (Object .entries (obj) 
        .filter (([k, v]) => v !== '') 
        .map (([k, v]) => [k, removeEmpties (v)]
      ))
  : obj

const input = {a: [{a: ['b','',]}], b: {a: ['b',''], b: {c:'e',f:''}}, c: 'd', e: '', f: ['g',''], date: new Date()}

console .log (removeEmpties (input))
.as-console-wrapper {min-height: 100% !important; top: 0}

但是可以将其推广到一个更可重用的函数,如下所示:

const deepFilter = (pred) =>  (obj) => 
  Array .isArray (obj)
    ? obj .filter (pred) .map (deepFilter (pred))
  : Object (obj) === obj
    ? Object .fromEntries (Object .entries (obj) 
        .filter (([k, v]) => pred(v)) 
        .map (([k, v]) => [k, deepFilter (pred) (v)]
      ))
  : obj

然后通过这种方式专门针对您的情况:

const removeEmpties = deepFilter (x => x !== '')