0

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/

2
  • 1
    filter might help here. Please may you share your attempt so far as a minimal reproducible example? Commented Jan 19, 2022 at 14:52
  • I have updated my question with the Fiddle please try it now. I did try to use the filter but I get some sort of null error Commented Jan 19, 2022 at 15:11

2 Answers 2

1

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);

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

Comments

1

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());

1 Comment

Thank you for the detailed explanation. It really helped me understand the methods :)

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.