Mam tablicę obiektów, które zawierają adresy. Muszę wykonać następujące czynności:

  • Wyodrębnij każdy kod pocztowy z wartości adresu.
  • Znajdź unikalne kody pocztowe i przechowuj liczbę duplikatów.
  • Przechowuj pierwszy adres dla każdego unikalnego kodu pocztowego w nowej tablicy wraz z liczbą duplikatów.

Oto mój obecny kod.

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

Ostatnia część powyżej kończy się na pierwszym meczu, ale tylko dla pierwszego kodu pocztowego. Myślałem, że w pętli to zadziała, ale tak nie jest.

Mój pożądany rezultat byłby taki:

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"

  }
]
2
Matt Simon 3 kwiecień 2020, 11:27

5 odpowiedzi

Najlepsza odpowiedź

Przyczyną, dla której Twoje obecne rozwiązanie nie działa, jest wiersz:

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

Zwracasz wynik indexOf, czyli -1, jeśli nie można znaleźć podłańcucha. -1 jest uważane za prawdziwe, co z kolei sygnalizuje find znalezioną wartość. Zmiana tego wiersza na następującą naprawia bieżący kod.

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

Mając powyższe na uwadze, osobiście wybrałbym inne rozwiązanie.

Możesz osiągnąć pożądane wyniki, grupując najpierw adresy na podstawie kodu pocztowego. Następnie utwórz tablicę wyjściową przy użyciu tych grup.

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);
2
3limin4t0r 3 kwiecień 2020, 10:18

Może to ci pomoże ... W 3 linijkach.

Jak policzyć zduplikowaną wartość w tablicy w 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);
0
bZezzz 3 kwiecień 2020, 09:07

Const postcodes = fullAddresses.split (","). Metoda podziału nie będzie działać. Nie powinieneś używać przecinka w nawiasach, ponieważ nie masz go w swoich wartościach adresowych. Zamiast tego użyj spacji.

1
Peter Akinlolu 3 kwiecień 2020, 08:51

Możesz ulepszyć funkcję wyszukiwania kodu pocztowego, ale reszta pozostaje taka sama.

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);
0
Adam Azad 3 kwiecień 2020, 08:57

Myślę, że metoda find musi być find(address => address.address.indexOf(postcode) > -1 (upewnij się, że zwraca wartość logiczną)


Zmieniono sposób zdobycia pincodoe, Zakładając, że jest to ostatni po splicie. (możesz to zmienić, ale główny problem może być powyżej)

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));
0
sivako 3 kwiecień 2020, 10:22