2

I have an array of objects which contain addresses. I need to perform the following:

  • Extract each postcode from address values.
  • Find unique postcodes and store amount of duplicates.
  • Store the first address for each unique postcode in a new array along with the number of duplicates.

Here is my current code.

const json = [
  { "id": "10093729341", "address": "1 Alpha Road CF14 6AA" },
  { "id": "10024750520", "address": "2 Alpha Road CF14 6AA" },
  { "id": "10025738368", "address": "3 Alpha Road CF14 6AF" },
  { "id": "10025738368", "address": "4 Alpha Road CF14 6AF" },
  { "id": "10025738368", "address": "4 Alpha Road CF14 6AB" }
]

let allPostcodes = [];

json.forEach(address => {
  const fullAddresses = address.address;
  const postcodes = fullAddresses.split(",").map(s => s.trim().match(/([A-Za-z]{1,2}\d{1,2})(\s?(\d?\w{2}))?/)).filter(e => e)[0][0]
  allPostcodes.push(postcodes);
});

const uniquePostcodes = [...new Set(allPostcodes)];

uniquePostcodes.forEach(postcode => {
  const addresses = json.find(address => address.address.indexOf(postcode));
  console.log(addresses.address);
});

The final part above stops at the first match but for the first postcode only. I thought that in a loop it would work but it doesn't.

My desired outcome would be this:

const array = [
  {
    "address": "1 Alpha Road CF14 6AA",
    "count": 2,
    "postcode": "CF14 6AA"
  },
  {
    "address": "3 Alpha Road CF14 6AF",
    "count": 2,
    "postcode": "CF14 6AF"

  },
  {
    "address": "4 Alpha Road CF14 6AB",
    "count": 1,
    "postcode": "CF14 6AB"

  }
]
Matt Simon
  • 25
  • 3

5 Answers5

2

The reason your current solution isn't working is due to the line:

const addresses = json.find(address => address.address.indexOf(postcode));

You return the indexOf result which is -1 if the substring can't be found. -1 is considdered truthy, which in turn signals find the the value is found. Changing this line to the following fixes your current code.

const addresses = json.find(address => address.address.indexOf(postcode) >= 0);
// or
const addresses = json.find(address => address.address.includes(postcode));

With the above being said, I'd personally would go for a different solution.

You can achieve the desired output by first grouping the addresses based upon postcode. Then build your output array using those groups.

const json = [
  { "id": "10093729341", "address": "1 Alpha Road CF14 6AA" },
  { "id": "10024750520", "address": "2 Alpha Road CF14 6AA" },
  { "id": "10025738368", "address": "3 Alpha Road CF14 6AF" },
  { "id": "10025738368", "address": "4 Alpha Road CF14 6AF" },
  { "id": "10025738368", "address": "4 Alpha Road CF14 6AB" }
];

// Group addresses by postcode.
const postcodeRegex = /([A-Za-z]{1,2}\d{1,2})(\s?(\d?\w{2}))?/;
const addressesByPostcode = new Map();

json.forEach(address => {
  const postcode = address.address.match(postcodeRegex);
  
  if (!addressesByPostcode.has(postcode[0]))
    addressesByPostcode.set(postcode[0], []);
  addressesByPostcode.get(postcode[0]).push(address);
});

// Build output array.
const array = Array.from(addressesByPostcode)
                   .map(([postcode, addresses]) => ({
                     address:  addresses[0].address,
                     count:    addresses.length,
                     postcode: postcode,
                   }));

// Display result.
console.log(array);
3limin4t0r
  • 19,353
  • 2
  • 31
  • 52
1

const postcodes = fullAddresses.split(","). The split method will not work. You shouldn't use a comma inside the parenthesis because you don't have one In your address values. Use space instead.

0

I think find method, need to be find(address => address.address.indexOf(postcode) > -1 (make sure return boolean value)


Changed way to get the pincodoe, Assumed it is last one after split. (you can change it, But the main issue may be above)

const json = [
  {
    id: "10093729341",
    address: "1 Alpha Road CF14 6AA"
  },
  {
    id: "10024750520",
    address: "2 Alpha Road CF14 6AA"
  },
  {
    id: "10025738368",
    address: "3 Alpha Road CF14 6AF"
  },
  {
    id: "10025738368",
    address: "4 Alpha Road CF14 6AF"
  },
  {
    id: "10025738368",
    address: "4 Alpha Road CF14 6AB"
  }
];

const codes = {};

json.forEach(({ address }) => {
  const postcode = address
    .split(" ")
    .slice(-2)
    .join(" ");
  codes[postcode] =
    postcode in codes
      ? { ...codes[postcode], count: codes[postcode].count + 1 }
      : { address, count: 1, postcode };
});

console.log(Object.values(codes));
Siva K V
  • 10,561
  • 2
  • 16
  • 29
0

You can improve the function of finding the postcode, but the rest remains the same.

const json = [
            {
                "id": "10093729341",
                "address": "1 Alpha Road CF14 6AA"
            },
            {
                "id": "10024750520",
                "address": "2 Alpha Road CF14 6AA"
            },
            {
                "id": "10025738368",
                "address": "3 Alpha Road CF14 6AF"
            },
            {
                "id": "10025738368",
                "address": "4 Alpha Road CF14 6AF"
            },
            {
                "id": "10025738368",
                "address": "4 Alpha Road CF14 6AB"
            }
        ]


/*
 * You can (and should) improve this later
 */
const getPostCode = address => address.split(" ").slice(3, 5).join(" ");


let r = json.reduce((res, o) => {
  // Find the post code 
  let postCode = getPostCode(o.address);
  // Find if the post code exists
  let pCodeExists = res.findIndex(add => add.postCode.indexOf(postCode) > -1);  
  // If the address exsits, increase the count
  if (pCodeExists > 0) {
    res[pCodeExists]['count']++; 
  // Otherwise, add a new entity
  } else {
    res.push({
      address: o.address,
      count: 1,
      postCode
    });
  }
  
  return res;

}, []);

console.log(r);
Adam Azad
  • 11,171
  • 5
  • 29
  • 70
0

Maybe it can help you... In 3 lines.

How to count duplicate value in an array in javascript

var counts = {};
your_array.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
concole.log(counts);

const json = [
            {
                "id": "10093729341",
                "address": "1 Alpha Road CF14 6AA"
            },
            {
                "id": "10024750520",
                "address": "2 Alpha Road CF14 6AA"
            },
            {
                "id": "10024750520",
                "address": "2 Alpha Road CF14 6AA"
            },
            {
                "id": "10025738368",
                "address": "3 Alpha Road CF14 6AF"
            },
            {
                "id": "10025738368",
                "address": "4 Alpha Road CF14 6AF"
            },
            {
                "id": "10025738368",
                "address": "4 Alpha Road CF14 6AB"
            }
        ]

let allPostcodes = [];
json.forEach(address => {
  const fullAddresses = address.address;
  const postcodes = fullAddresses.split(",").map(s => s.trim().match(/([A-Za-z]{1,2}\d{1,2})(\s?(\d?\w{2}))?/)).filter(e => e)[0][0]
  allPostcodes.push(postcodes);

});


var counts = {};
allPostcodes.forEach(function(x) { counts[x] = (counts[x] || 0)+1; });
console.log(counts);
bZezzz
  • 972
  • 9
  • 22