Search code examples
javascriptjavascript-objectspass-by-reference

Is it efficient to create multiple keys pointing to the same object?


I have an array of countries, where each country have three properties.

const countries = [
  { name: "Poland", alpha: "POL", code: "616" },
  { name: "Hungary", alpha: "HUN", code: "348" },
  // and so on...
]

Later on I want to easily access each country by any of these properties.

I was thinking of reducing this array to an object that would have three keys for each country pointing to the very same country object.

Something like this:

const countriesObject = countries.reduce((object, country) => {
  const { name, alpha, code } = country;

  // Create individual country object
  object[name] = { ...country };

  // Reference just created country object 
  object[code] = object[name];
  object[alpha] = object[name];

  return object;
});

In the end I could access each country object either by its name, code or alpha.

countriesObject["Poland"] // → 
countriesObject["POL"]    // → The same object
countriesObject["616"]    // → 

My question is, would it be considered good practice, or there are some better ways to achieve the same or similar result?

Thank you!


Solution

  • That's fine, as all of those keys, as you correctly noted, will be pointing to the same object. The biggest problem that I see here is that it's easy to reduce readability of the code by using this approach. Let's say we have this fragment:

    console.log( countriesObject[id] );
    

    The question is, what is id here? Is it full country name? or just alpha? or code? You might just not care, true, but if you do, consider giving them additional structure:

    const countriesObject = countries.reduce((object, country) => {
      const { name, alpha, code } = country;
      const countryCopy = { ...country };
    
      // it makes sense to place them on the same line to show the intent
      object.name[name] = object.code[code] = object.alpha[alpha] = countryCopy;
      return object;
    }, { name: {}, code: {}, alpha: {} });
    

    Another potential issue is that you won't be able to drop the countries easily from this object; it's not enough to delete just a single key pointing to it, you'll have to go and remove all three. But that doesn't seem to be a big thing here; this looks more like a dictionary.