Skip to content Skip to sidebar Skip to footer

Loop Through Complex React State To Remove All Empty Strings

I have a complex react state that is structured like this: { a: [ { a: ['b','',] } ], b: { a: ['b',''], b: {c:'e',f:''}

Solution 1:

You can pass a replacer function into your JSON.stringify() method. Returning undefined from the replacement function will remove the key-value pair, so you can return undefined when you encounter an empty string. Likewise, when you encounter an array, you can filter it to only contain values which are non-empty strings.

See example below:

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

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

Solution 2:

You can also create a new object with a dedicated function that recursively removes the empty strings. Something like this:

constremoveEmpties = (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: newDate()}

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

But that could be generalized to a more reusable functionlike this:

constdeepFilter = (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

And then specialized for your case this way:

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

Post a Comment for "Loop Through Complex React State To Remove All Empty Strings"