0

I have array like this:

[
    {givenName: "Name 1", phoneNumbers: [
        {label: "mobile", id: "5", number: "097 726 94 36"},
        {label: "other", id: "558", number: "0977269436"},
        {label: "other", id: "559", number: "0977269436"}
    ]},
    {givenName: "Name 2", phoneNumbers: [
        {label: "mobile", id: "5", number: "0968234838"},
        {label: "other", id: "558", number: "0966766555"},
        {label: "other", id: "559", number: "0966766555"}
    ]},
    {givenName: "Name 3", phoneNumbers: [
        {label: "other", id: "558", number: "0965777238"},
        {label: "other", id: "559", number: "0965777238"}
    ]},
]

Then I filter the number to get a number that is less than or equal to 10 digits. Then returns an array with items that do not match a number.

I then iterate through each of the above items, then push it into an empty array to get each individual item.

And my final result array like so:

[
    {givenName: "Name 1", phoneNumbers: "0977269436"},
    {givenName: "Name 2", phoneNumbers: "0968234838"},
    {givenName: "Name 2", phoneNumbers: "0966766555"},
    {givenName: "Name 3", phoneNumbers: "0965777238"}
]

Bellow is my code, it works normally.

I just wanted to ask if there's a better way than my code.:

const contacts = [
  {givenName: "Name 1", phoneNumbers: [
    {label: "mobile", id: "5", number: "097 726 94 36"},
    {label: "other", id: "558", number: "0977269436"},
    {label: "other", id: "559", number: "0977269436"}
  ]},
  {givenName: "Name 2", phoneNumbers: [
    {label: "mobile", id: "5", number: "0968234838"},
    {label: "other", id: "558", number: "0966766555"},
    {label: "other", id: "559", number: "0966766555"}
  ]},
  {givenName: "Name 3", phoneNumbers: [
    {label: "other", id: "558", number: "0965777238"},
    {label: "other", id: "559", number: "0965777238"}
  ]},
]

const listContactsLocal = [];
const contactFilter = contacts.map((item) => {
  const listPhone = item?.phoneNumbers.filter((phone, index) => {
    return (
      index === item?.phoneNumbers.findIndex((obj) => {
        if (phone.number.length > 11) {
          return;
        }
        return obj.number === phone.number;
      })
    );
  });

  return {
    givenName: item?.givenName,
    phoneNumbers: listPhone,
  };
});

contactFilter.map((item) => {
  return item?.phoneNumbers.map((phone) => {
    return listContactsLocal.push({
      givenName: item?.givenName,
      phoneNumbers: phone?.number,
    });
  });
});


console.log(listContactsLocal)
.as-console-wrapper{min-height:100%;}

Sorry about my English.

Thank you. :))

4
  • So you always want to have one phone number? Even when there are no duplicates? Commented Mar 9, 2021 at 15:15
  • Yes, I just want to have one phone number. @Gh05d Commented Mar 9, 2021 at 15:28
  • This probably belongs on Code Review Commented Mar 9, 2021 at 15:45
  • Thank for your information @pilchard Commented Mar 9, 2021 at 15:47

3 Answers 3

1

You can simplify this down to a reduce() call inside a flatMap to flatten the resulting nested arrays.

const contacts = [{ givenName: "Name 1", phoneNumbers: [{ label: "mobile", id: "5", number: "097 726 94 36" }, { label: "other", id: "558", number: "0977269436" }, { label: "other", id: "559", number: "0977269436" }] }, { givenName: "Name 2", phoneNumbers: [{ label: "mobile", id: "5", number: "0968234838" }, { label: "other", id: "558", number: "0966766555" }, { label: "other", id: "559", number: "0966766555" }] }, { givenName: "Name 3", phoneNumbers: [{ label: "other", id: "558", number: "0965777238" }, { label: "other", id: "559", number: "0965777238" }] },];

const
  isFirstInstance = (number, index, arr) => arr.findIndex(o => o.number === number) === index,
  result = contacts.flatMap(({ givenName, phoneNumbers }) => (
    phoneNumbers.reduce((acc, { number }, i) => {
      if (number.length < 11 && isFirstInstance(number, i, phoneNumbers)) {
        acc.push({ givenName, phoneNumbers: number })
      }
      return acc;
    }, [])
  ));

console.log(result);
.as-console-wrapper { max-height: 100% !important; top: 0; }

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

Comments

1

you can use Set in javascript to have the unique number and add this logic bellow:

    let my_new_array = [].concat.apply([],contacts.map(obj => {
        let numberArray = [...new Set(obj.phoneNumbers.map(phoneobj => 
             phoneobj.number.replace(/\s+/g, '')))]
          return numberArray.map(number => ({
          givenName: obj.givenName,
          phoneNumbers: number
      }))
    }))

I test it in my IDE and this is the result

enter image description here

3 Comments

How about I want to split it into separate arrays?
Sorry i didn't flaten :) ... i edited my answer :D
Yeah, Thank you so much :)
0

All you need is one reduce:

const res = contacts.reduce((acc, cV) => {
   acc.push({
    givenName: cV.givenName,
    phoneNumber: cV.phoneNumbers?.find(phone => phone.number.length <= 10)?.number,
  });
  return acc
}, []);

What happens is that you iterate through your array and search phoneNumbers - if it exists - for a valid number. I renamed the variable in the result to phoneNumber to better reflect what it is.

You can try it out in this codepen.

3 Comments

Should the Name 2 value have two different numbers? You can check my console.log.
Ah, so you mean if there are several numbers then every not-duplicated number should have it's own entry?
Yah. I just want to have one phone number.

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.