WildThing
WildThing

Reputation: 1275

JavaScript: delete an Object's key which is nested inside an another Object when value is an empty string

How to write a JS loop that can achieve this?

raw data:

[
{
    "firstName": "James",
    "lastName": "Doe",
    "emails": [
        {
            "emailType": "WORK",
            "address": ""
        },
        {
            "emailType": "PERSONAL",
            "address": "[email protected]"
        }
    ],
    "relationship": "boyfriend",
    "phones": [
        {
            "phoneType": "HOME",
            "phoneNumber": "(514) 888-9999"
        },
        {
            "phoneType": "CELL",
            "phoneNumber": "(123) 123-4567"
        },
        {
            "phoneType": "WORK",
            "phoneNumber": "(415) 875-9999 "
        }
    ],
    "callSequence": 0
},
{
    "firstName": "John",
    "lastName": "Doe",
    "emails": [
        {
            "emailType": "WORK",
            "address": ""
        },
        {
            "emailType": "PERSONAL",
            "address": "[email protected]"
        }
    ],
    "relationship": "ex-husband",
    "phones": [
        {
            "phoneType": "HOME",
            "phoneNumber": ""
        },
        {
            "phoneType": "CELL",
            "phoneNumber": "(111) 111-1111"
        },
        {
            "phoneType": "WORK",
            "phoneNumber": ""
        }
    ],
    "callSequence": 0
}
]

Expected results:

[
{
    "firstName": "James",
    "lastName": "Doe",
    "emails": [
        {
            "emailType": "PERSONAL",
            "address": "[email protected]"
        }
    ],
    "relationship": "boyfriend",
    "phones": [
        {
            "phoneType": "HOME",
            "phoneNumber": "(514) 888-9999"
        },
        {
            "phoneType": "CELL",
            "phoneNumber": "(123) 123-4567"
        },
        {
            "phoneType": "WORK",
            "phoneNumber": "(415) 875-9999 "
        }
    ],
    "callSequence": 0
},
{
    "firstName": "John",
    "lastName": "Doe",
    "emails": [
        {
            "emailType": "PERSONAL",
            "address": "[email protected]"
        }
    ],
    "relationship": "ex-husband",
    "phones": [
        {
            "phoneType": "CELL",
            "phoneNumber": "(111) 111-1111"
        },
    ],
    "callSequence": 0
}
]

as you can see if the phoneNumber or mail address is empty, It should filter out and remove the complete property. As it is in a loop and there can be multiple objects, I am not sure how to write a loop to achieve this required result.

DEMO: https://jsfiddle.net/pa6ug53b/1/

Upvotes: 0

Views: 35

Answers (2)

Shan
Shan

Reputation: 1568

You can map over the array and then filter the objects inside the array for specific key.

const result = yourArray.map((obj) => ({
  ...obj,
  emails: obj.emails.filter((emailObj) => emailObj.address),
  phones: obj.phones.filter((phoneObj) => phoneObj.phoneNumber)
}));

const yourArray = [
  {
    firstName: "James",
    lastName: "Doe",
    emails: [
      {
        emailType: "WORK",
        address: ""
      },
      {
        emailType: "PERSONAL",
        address: "[email protected]"
      }
    ],
    relationship: "boyfriend",
    phones: [
      {
        phoneType: "HOME",
        phoneNumber: "(514) 888-9999"
      },
      {
        phoneType: "CELL",
        phoneNumber: "(123) 123-4567"
      },
      {
        phoneType: "WORK",
        phoneNumber: "(415) 875-9999 "
      }
    ],
    callSequence: 0
  },
  {
    firstName: "John",
    lastName: "Doe",
    emails: [
      {
        emailType: "WORK",
        address: ""
      },
      {
        emailType: "PERSONAL",
        address: "[email protected]"
      }
    ],
    relationship: "ex-husband",
    phones: [
      {
        phoneType: "HOME",
        phoneNumber: ""
      },
      {
        phoneType: "CELL",
        phoneNumber: "(111) 111-1111"
      },
      {
        phoneType: "WORK",
        phoneNumber: ""
      }
    ],
    callSequence: 0
  }
];

const result = yourArray.map((obj) => ({
  ...obj,
  emails: obj.emails.filter((emailObj) => emailObj.address),
  phones: obj.phones.filter((phoneObj) => phoneObj.phoneNumber)
}));

console.log(result);

Upvotes: 1

jsN00b
jsN00b

Reputation: 3691

Here is one possible implementation to achieve the desired result.

const processObjArray = (arr = [], colName = 'phoneNumber') => (
    arr.filter(o => o[colName] && o[colName].length > 0)
);

const removeEmptyValues = (arr = data) => arr.map(o => ({
  ...o,
  emails: processObjArray(o.emails, 'address'),
  phones: processObjArray(o.phones)
}));

console.log(removeEmptyValues());

Explanation

  1. Use .map to iterate over the data.
  2. For emails, phones 'process' the array (to remove empty address, phoneNumber)
  3. The processing of the array is handled in a separate method (processObjArray) that employs .filter

And here's the code-snippet:

const data = [{
    "firstName": "James",
    "lastName": "Doe",
    "emails": [{
        "emailType": "WORK",
        "address": ""
      },
      {
        "emailType": "PERSONAL",
        "address": "[email protected]"
      }
    ],
    "relationship": "boyfriend",
    "phones": [{
        "phoneType": "HOME",
        "phoneNumber": "(514) 888-9999"
      },
      {
        "phoneType": "CELL",
        "phoneNumber": "(123) 123-4567"
      },
      {
        "phoneType": "WORK",
        "phoneNumber": "(415) 875-9999 "
      }
    ],
    "callSequence": 0
  },
  {
    "firstName": "John",
    "lastName": "Doe",
    "emails": [{
        "emailType": "WORK",
        "address": ""
      },
      {
        "emailType": "PERSONAL",
        "address": "[email protected]"
      }
    ],
    "relationship": "ex-husband",
    "phones": [{
        "phoneType": "HOME",
        "phoneNumber": ""
      },
      {
        "phoneType": "CELL",
        "phoneNumber": "(111) 111-1111"
      },
      {
        "phoneType": "WORK",
        "phoneNumber": ""
      }
    ],
    "callSequence": 0
  }
];


const processObjArray = (arr = [], colName = 'phoneNumber') => (arr.filter(o => o[colName] && o[colName].length > 0));

const removeEmptyValues = (arr = data) => arr.map(o => ({ ...o,
  emails: processObjArray(o.emails, 'address'),
  phones: processObjArray(o.phones)
}));

console.log(removeEmptyValues());

Upvotes: 1

Related Questions