1
\$\begingroup\$

I have different format of address in an array, those format looks like this

lastname/firstname/_/country/postalCode/_/regionId/city/addressFirst/addressSecond/_/phone

lastname => a part of the address (noted AddressPart) / => a separation _ => a line break

the above entire would do

lastname firstname
country postalCode
regionId city addressFirst addressSecond
phone

now, I have a method, where I basically want to pass a parameter what part I am interested in, and get the resulting format:

f.e

 input : ["country", "postalCode"]
 return "country/postalCode

 input : ["lastname", "firstname", "regionId"]
 return "lastname/firstname/_/regionId"

 input : ["firstname", "country", "regionId", "city"]
 return "firstname/_/country/_/regionId/city"

 input : ["country", "regionId", "phone"]
 return "country/_/regionId/_/phone"

Here is the method :

  type AddressPart = "firstname" | "lastname" | ... | "phone";
  const allAddressParts = ["firstname", "lastname", ... ,"phone"];

  static getLocaleAddress(
    parts: AddressPart[]
  ) {
    let addressFormat = `lastname/firstname/_/country/postalCode/_/regionId/city/addressFirst/addressSecond/_/phone`;
    // (1)
    const toRemove = allAddressParts.filter((part) => !parts.includes(part));
    // (2)
    toRemove.forEach((part) => {
      addressFormat = addressFormat
        .replace(`_/${part}/_`, '_')
        .replace(new RegExp(part + '/?'), '')
        .replace(/^(_\/)+/, '')
        .replace(/\/(_\/)*$/, '');
    });
    return addressFormat.split('/');
  }

What I don't like in what I did is :

  1. I replace items, so I need to filter from the list of parts the one I want, to keep the one I want to remove
  2. it is 4 replaces operations, and I was wondering if it was improvable.

Thanks for the tips :x

\$\endgroup\$
1
\$\begingroup\$

What I don't like in what I did is :

  1. I replace items, so I need to filter from the list of parts the one I want, to keep the one I want to remove

  2. it is 4 replaces operations, and I was wondering if it was improvable.


It is possible to avoid replacing items. For example,

'use strict';

function getLocaleAddress(parts) {
    // field and line separators
    const fieldSep = "/";
    const lineBreak = "_";

    // address parts plus lineBreak as set
    parts = new Set(parts).add(lineBreak);

    // format template as array
    const format = (
       "lastname/firstname/_/" +
        "country/postalCode/_/" +
        "regionId/city/addressFirst/addressSecond/_/" +
        "phone"        
        )
        .split(fieldSep)
    ;

    // selected address parts as array
    let selected = [];
    let inLine = false;
    for (const field of format) {
        if (parts.has(field)) {
            if (field !== lineBreak) {
                inLine = true;
            }
            if (inLine) {
                selected.push(field);
            }
        }
        if (field === lineBreak) {
            inLine = false;
        }
    }
    const end = selected.length - 1;
    if (end >= 0 && selected[end] === lineBreak) {
        selected.pop();
    }
    return selected;
}

function test(input) {
    const fieldSep = "/";
    console.log(
        "\n", input, 
        "\n", getLocaleAddress(input).join(fieldSep)
    );
}

test(["country", "postalCode"]);
test(["lastname", "firstname", "regionId"]);
test(["firstname", "country", "regionId", "city"]);
test(["country", "regionId", "phone"]);

$ node cr.address.js

 [ 'country', 'postalCode' ] 
 country/postalCode

 [ 'lastname', 'firstname', 'regionId' ] 
 lastname/firstname/_/regionId

 [ 'firstname', 'country', 'regionId', 'city' ] 
 firstname/_/country/_/regionId/city

 [ 'country', 'regionId', 'phone' ] 
 country/_/regionId/_/phone

$ 

I used JSBench.me and your test cases to compare my code to your code. My code was fastest. Your code was 70.3% slower.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.