Home > Software engineering >  Join object string values that exist and in a custom order
Join object string values that exist and in a custom order

Time:01-18

I am being passed an object containing address data (in alphabetical order) that I am wanting to extract a sub-set of to display, but in a different order.

Not all of the keys will have data in all of the time, sometimes having an empty string instead of nothing at all.

const address = {
  buildingName: '',
  company: 'My org',
  county: 'My County',
  postCode: 'My Postcode',
  streetName: 'My street',
  townCity: 'My Town'
};

I know that I can get all of the present values out by doing:

Object.keys(address).filter(Boolean).join(', ')

However I am wanting the order of the information being output to be: company, buildingName, streetName, townCity, county, postCode.

Is there any way in which I can alter my current solution, or do I need a different approach entirely?

CodePudding user response:

I managed to get a solution combining Jan Pfeifer and Gog's solutions to some extent, along with my own experimentation.

It also transpired that fields with no value weren't being returned as empty strings, but weren't included, so that made things a bit easier.

const ADDRESS_ORDER = ['company', 'buildingName', 'streetName', 'townCity', 'county', 'postCode'];

return const addressString = ADDRESS_ORDER
    .filter(detail => Object.keys(address).includes(detail))
    .map(key => address[key])
    .join(', ');

const ADDRESS_ORDER = ['company', 'buildingName', 'streetName', 'townCity', 'county', 'postCode'];

const address = {
  company: 'My org',
  county: 'My County',
  postCode: 'My Postcode',
  streetName: 'My street',
  townCity: 'My Town'
};

const result = ADDRESS_ORDER
    .filter(detail => Object.keys(address).includes(detail))
    .map(key => address[key])
    .join(', ');
    
console.log({result});

If this was any longer or more complex, I would consider tidying up by combining the fileter and map into a reduce, but I don't think it warrants this at the moment.

CodePudding user response:

Because you need custom order you will have to create that object manually. You can use template array, but that is more or less the same solution.

const address = {
    buildingName: '',
    company: 'My org',
    county: 'My County',
    postCode: 'My Postcode',
    streetName: 'My street',
    townCity: 'My Town'
};

const tmp = ["company", "buildingName", "streetName", "townCity", "county", "postCode"];
let s = "";
tmp.forEach(key => {
    const v = address[key];
    if(v) {
        if(s) s  = ", ";
        s  = v;
    }
});
console.log(s);

CodePudding user response:

You could create an addressOrder array, to specify the order of the various address components, then use Array.reduce() to add to the output address components.

We'd only add the address to the output if it's present in the address object.

Finally we'd join the address components using the provided delimiter.

const address = {
  buildingName: 'Nakatomi Towers',
  company: 'Nakatomi Corp.',
  county: 'LA County',
  postCode: '90067',
  streetName: 'Century City',
  townCity: 'LA'
};

function formatAddress(address, addressOrder, delimiter = ', ') { 
    return addressOrder.reduce((outputFields, field) => { 
        if (address[field]) {
            outputFields.push(address[field]);  
        }
        return outputFields;
    }, []).join(delimiter);
}

const order1 = ['company','buildingName','streetName','townCity','county','postCode']
const order2 = ['buildingName','streetName','townCity','postCode']

console.log('Address:', formatAddress(address, order1))
console.log('\nAddress (alt. format):\n'   formatAddress(address, order2, '\n'))
.as-console-wrapper { max-height: 100% !important; }

  • Related