What would be the best/fastest way to access this data?

Hi,
Elixir and Phoenix newbie here… I’m building a test project where I have the list of countries and currencies. I’ve built a form where people can choose the country and I want the currency to be selected automatically based on the selected country. I would like to know, what would be the best way to structure the data for countries and currencies?

[
      {"Australia", "AUD"},
      {"Austria", "EUR"},
      {"Canada", "CAD"},
      {"United States", "USD"}
]
[
      %{:name => "Australia", :currency => "AUD"},
      %{:name => "Austria", :currency => "EUR"},
      %{:name => "Canada", :currency => "CAD"},
      %{:name => "United States", :currency => "USD"},
]

Should I use list of tupples, list of maps or maybe something else? This list should be available as a dropdown inside the form.

Tuples probably would be the best there as it would use the least space.

2 Likes

Tuples are good, but for quick search I would prefer a map of tuples, with the key being the search key…

If You have a list, it will take longer to search when toggling a field from the value of another field.

2 Likes

If there is anything I learned over the years of optimization: never make assumptions, first measure, then decide. You should be able to write a little program with a decent data set and run some tests to decide for yourself which kind of data structure best matches your problem.

1 Like

This sounds interesting, could you please give me an example? I’m a beginner at Elixir so this is all new and a little bit confusing to me.

Enum.group_by can help You turn a list into a map.

But for small data it might not be worth it.

2 Likes

I’ve played with it a bit and here’s what I came with;

countries = 
%{
      "Australia" => "AUD",
      "Austria" => "EUR",
      "Canada" => "CAD",
      "United States" => "USD"
}

To list all the countries in the select box all I have to do now is:

Map.keys(countries)

To get the matching currency:

Map.get(countries, country)

country in this case comes from the database as the users should select their country in the step before so it’s already saved in the database.

Another way to access the data would be…

countries[country]
2 Likes

There are only 195 countries in the world. Even the slowest PC built since 1990 will process this small list in milliseconds or less. So, I think don’t worry.
Pull down lists (drop down lists) on clients side should never lead to performance problems because their nature is to hold only a small list of values.
But of course the map structure is the fastest because it uses hashes in a tree structure. But don’t forget, keys of a map are not sorted and cannot be sorted. In many cases a pull-down list should be sorted.

2 Likes

If you’re only ever going to be using currencies, a simple list of tuples will do fine. If you’re processing it in some way such that that yields poor performance, a map from name to currency would be better. But the big question is, what are the chances of needing to add more info, like population, GDP, area, capital(s), etc.? If that’s a reasonable possibility, you may want to use a map from country names to a map of assorted info. Frex:

%{
  "Australia" => %{currency: "AUD", language: "English", continent: "Australia"},
  "Austria"   => %{currency: "EUR", language: "German",  continent: "Europe"},
  # etc.
}

You could even make a module to declare the structure of the inner maps as structs, to make access to the values easier and more reliable, e.g., country.language rather than country["language"].

1 Like

Now that you have a few ways to do it, I recommend spending 5 minutes playing around with benchee, post back your findings.

1 Like