1

The sample json object. I tried to remove all "-", "N/A", and "" from this JSON object.

{
  name: { first: 'Robert', middle: '', last: 'Smith' },
  age: 25,
  DOB: '-',
  hobbies: [ 'running', 'coding', '-' ],
  education: { highschool: 'N/A', college: 'Yale' }
}

I did something like it. but couldn't manage to remove <1 empty item> from the array

{
  name: { first: 'Robert', last: 'Smith' },
  age: 25,
  hobbies: [ 'running', 'coding', <1 empty item> ],
  education: { college: 'Yale' }
}

How can I remove the <1 empty item> from the json object.

This is my code

axios.get("https://coderbyte.com/api/challenges/json/json-cleaning")
  .then((res) => {
    let parseData = res.data;

    const removeValue = (obj) => {
      Object.keys(obj).forEach(k => 
        
        // console.log(obj[k])
        (obj[k] && obj[k] === "-") && 
        delete obj[k] ||

        (obj[k] && typeof obj[k] === 'object')
        && removeValue(obj[k]) || 
        
        (!obj[k] && obj[k] !== undefined) && 
        delete obj[k] || 
        
        (obj[k] && obj[k] === "N/A") && 
        delete obj[k]


      );
      return obj
    }

    newData = removeValue(parseData)

    console.log(newData)
  })
1
  • and in case the array becomes empty, should it also be removed? Commented Aug 13, 2022 at 15:59

5 Answers 5

1

Using delete is fine on objects, but for arrays, it will remove the property while keeping the array's .length the same. So, for example, delete-ing the 3rd item of an array of length 3 will result in an array with two array-indexed properties (0 and 1), but keep its length of 3.

Check if the object is an array. If it's an array, .filter instead.

const payload = {
  name: { first: 'Robert', middle: '', last: 'Smith' },
  age: 25,
  DOB: '-',
  hobbies: [ 'running', 'coding', '-' ],
  education: { highschool: 'N/A', college: 'Yale' }
};
const isGoodValue = val => val && val !== '-' && val !== 'N/A';

const removeBadValues = (obj) => {
  if (Array.isArray(obj)) {
    return obj
      .filter(isGoodValue)
      .map(removeBadValues);
  }
  if (typeof obj === 'object') {
    for (const [key, value] of Object.entries(obj)) {
      if (!isGoodValue(value)) {
        delete obj[key];
      } else {
        obj[key] = removeBadValues(value);
      }
    }
  }
  return obj;
}
const newData = removeBadValues(payload)
console.log(newData)

Sign up to request clarification or add additional context in comments.

Comments

1

You can use this

obj.hobbies.splice(obj.hobbies.indexOf('-'), 1);

Where obj is the object you pass in.

Comments

1

Using JSON stringify with replacer argument, Using this method also means the replacement is done to all nested keys within nested objects:

let obj = {
  name: { first: "Robert", middle: "", last: "Smith" },
  age: 25,
  DOB: "-",
  hobbies: ["running", "coding", "-"],
  education: { highschool: "N/A", college: "Yale" },
};
function replacer(key, value) {
  if (value === "N/A" || value === "") {
    return undefined;
  } else if (Array.isArray(value)) {
    return value.filter((el) => el != "-");
  }
  return value;
}
console.log(JSON.stringify(obj, replacer, 4));

Note: Use JSON.parse() to turn it back into an object.

Comments

1

var test = {
  DOB: '-',
  test2: 'somestring',
  test3: 3,
}

function clean(obj) {
  for (var propName in obj) {
    if (obj[propName] === '-' || obj[propName] === undefined) {
      delete obj[propName];
    }
  }
  return obj
}

console.log(test);
console.log(clean(test));

Comments

1

use Array.prototype.splice()

complete code (recursive) with also empty array or empty object removal

const data_row = 
  { name      : { first: 'Robert', middle: '', last: 'Smith'} 
  , age       : 25
  , DOB       : '-'
  , hobbies   : [ 'running', 'coding', '-'] 
  , education : { highschool: 'N/A', college: 'Yale'} 
  } 
     
clearner( data_row )
console.log( data_row )


function clearner( obj )
  {
  const bad = ['-', 'N/A',  '']
  
  for (prop in obj)  
    {
    switch (Array.isArray(obj[prop]) ? 'array' : typeof obj[prop])
      {
      case 'array':
        for (let i=obj[prop].length;i--;)
          if ( bad.includes( obj[prop][i] ))
            obj[prop].splice(i,1); 
        break;
      case 'string':
        if (bad.includes( obj[prop] ))
          delete obj[prop]
        break;
      case 'object':
        clearner( obj[prop] )
        break;
      } 
    if ( obj[prop] && obj[prop].length === 0 )  // empty array or empty object removal
      delete obj[prop]  
  } }
.as-console-wrapper {max-height: 100% !important;top: 0;}
.as-console-row::after {display: none !important;}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.