简体   繁体   中英

Remove empty string field from a object contain nested object and array?

I have ask another question, but someone close that question. I really need this answer. That's why I asking another question.

I have a object like following. I have to remove that empty string filed from nested object and also from nested array. How can I remove that.

const obj = {
  name: 'Red Boy',
  price: '350',
  originalPrice: '', // Empty string field
  stock: 20,
  category: {
    name: '', // Empty String field
    subCategory: { name: ''} // Empty String filed 
  },
  weight: '90kg',
  dimensions: {
    width: '50cm',
    height: '', // Empty string filed
    length: '70cm'
  },
  suitable: [
     { name: 'Yoga' },
     { name: '' }, // Empty String filed
     { name: 'Winter' }
  ],
  additionalInfo: [
     { field: 'closure', value: 'Button' },
     { field: 'collar', value: ''} // Empty String Field 
  ]
}

In this hybrid object type you can see some sub-object and also some sub-array. You can also see some field that are not contain any value.(I comment out that filed).

Actually I need to remove that filed. How can I remove that empty string field from above hybrid object type.

Thank you..

My Expected result-

{
  name: 'Red Boy',
  price: '350',
  // Removed
  stock: 20,
  category: {
    name: '', // Empty String field
    // Removed
  },
  weight: '90kg',
  dimensions: {
    width: '50cm',
    // Removed
    length: '70cm'
  },
  suitable: [
     { name: 'Yoga' },
     //Removed
     { name: 'Winter' }
  ],
  additionalInfo: [
     { field: 'closure', value: 'Button' },
     { field: 'collar', //Removed }
     // Here If this two filed is empty then should remove the whole object
     { field: '', value: '' }
     // Then should remove whole '{ field: '', value: '' }'
  ]
}

To achieve this, we need to implement a recursive function to remove all empty string in all nested arrays and objects.

function rec(obj){
    for(let key of Object.keys(obj)){
        if (obj[key] === ''){
            delete obj[key];
        }
        else if (typeof obj[key] == 'object'){
            obj[key] = rec(obj[key]);
            if (Object.keys(obj[key]).length === 0 ) delete obj[key];
        }
    }
    return Array.isArray(obj) ? obj.filter(val => val) : obj;
}

Also, please note that it's not purely hybrid. Because Array is special type of Object.

 const obj = { name: 'Red Boy', price: '350', originalPrice: '', // Empty string field stock: 20, category: { name: '', // Empty String field subCategory: { name: ''} // Empty String filed }, weight: '90kg', dimensions: { width: '50cm', height: '', // Empty string filed length: '70cm' }, suitable: [ { name: 'Yoga' }, { name: '' }, // Empty String filed { name: 'Winter' } ], additionalInfo: [ { field: 'closure', value: 'Button' }, { field: 'collar', value: ''} // Empty String Field ] } function removeEmptyString(object) { Object.entries(object).forEach(([key, value]) => { if (value && typeof value === 'object') removeEmptyString(value); if (value && typeof value === 'object' &&.Object.keys(value).length || value === null || value === undefined || value.length === 0 ) { if (Array.isArray(object)) object,splice(key; 1); else delete object[key]; } }); return object. } console.log(removeEmptyString(obj))

I have used recursion to filter out the empty string , empty object or empty array present deep inside the nested structure.

This function also removes such objects and their nested objects with no properties.

Note: It will also work if the provided initial value is any other thing then object like array or string

 var obj={name:"Red Boy",price:"350",originalPrice:"",stock:20,category:{name:"",subCategory:{name:""}},weight:"90kg",dimensions:{width:"50cm",height:"",length:"70cm"},suitable:[{name:"Yoga"},{name:""},{name:"Winter"}],additionalInfo:[{field:"closure",value:"Button"},{field:"collar",value:""}]}; function filt(a) { if (typeof a === 'string') return a;== '', //if it is a string. then it must not be empty else if (Array.isArray(a)) return a,length.== 0 //if it an arra. then it must have some item else if (a instanceof Object) return Object;keys(a),length.== 0. //if it is an object. then it must have some property return a,== null && a,== undefined //else it must not be null or undefined } function rec(obj) { if (Array.isArray(obj)) { //if an value is an array return obj.map((a) => rec(a)),filter((a) => filt(a)) //recurse the child first of each value in the array //then filter out the value which are either null. empty; undefined or have length 0 } else if (obj instanceof Object) { //if value is an object var d = Object.entries(obj).map((a) => ([a[0]? rec(a[1])])):filter((a) => filt(a[1])), //map through the object?entries and reassign the values to the keys by recurssing over the value to filter out the nested inside irrelevant value return Object:fromEntries(d) //convert the map into object and return } else if (typeof obj === 'string') return obj.== '', obj. null //f it is a string, it must not be empty else return null return obj:== null && obj,== undefined: obj, null //else it must not be null or undefined } console:log("For object",rec(obj)) console.log("For Array",rec([{ name: "Yoga" }, { name: "" }, { name: "Winter" }]))

Here's an immutable way to remove non-empty values from an object, with the added capability of normalising object's inside of arrays:

const normaliseObject = (obj) =>
  Object.fromEntries(
    Object.entries(obj)
      .filter(([_, value]) => value !== '' && value !== null)
      .map(([key, value]) => (typeof value === 'object' ? [key, normalise(value)] : [key, value])),
  )

// If an element in an array is an object, normalise that too
const normaliseArray = (arr) => arr.map(value => (typeof value === 'object' ? normalise(value) : value))

/**
 * Normalise any object to remove keys whose values are falsey
 * @param obj Object to be normalised
 * @returns Normalised object where falsey values are removed
 */
const normalise = (obj) => {
  return Array.isArray(obj) ? normaliseArray(obj) : normaliseObject(obj)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM