Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 2 years ago.
Improve this question
I'm looking at building a form which prompts a user for their timezone. I've looked at the 'Google approach' and it seems to work pretty well. You first select a country from a drop down list and based on the selection, it populates the drop down list with the time zone options. I've search all over for a decent database with a country - timezone relationship but can't seem to find one. Does anyone know where i can find one?
Using Noda Time and the .NET Framework Culture and TimeZoneInfo classes
We managed to create a Json File with the Following entries which worked for us.
CountryName
2LetterIsoCountryCode
3LetterIsoCountryCode
IANATimezones
WindowsTimezones
Each Entry contains the list of available timezone for each country.
JsonFile here
Have you tried zoneinfo? http://www.twinsun.com/tz/tz-link.htm
"The public-domain time zone database contains code and data that represent the history of local time for many representative locations around the globe. It is updated periodically to reflect changes made by political bodies to time zone boundaries, UTC offsets, and daylight-saving rules. This database (often called tz or zoneinfo) is used by several implementations, including the GNU C Library used in GNU/Linux, FreeBSD, NetBSD, OpenBSD, Cygwin, DJGPP, AIX, Mac OS X, OpenVMS, Oracle Database, Solaris, Tru64, and UnixWare."
Hope that helps :)
The official mappings are found in the zone.tab file of the IANA time zone database.
There is also a newer version of this file, which covers cases where a time zone may be in use by more than one country. It is also in the IANA time zone database, and is called zone1970.tab.
Visit http://www.iana.org/time-zones/repository/tz-link.html
Download a Data file.
Check out the files iso3166.tab and zone.tab - between them they have everything you need.
timezonedb: https://timezonedb.com/
could also be mentioned. You can go to download page and find what format is most suitable for your project.
[
{name: "Afghanistan", code: "AF", gmt: "(UTC+04:30)"},
{name: "Albania", code: "AL", gmt: "(UTC+01:00)"},
{name: "Algeria", code: "DZ", gmt: "(UTC+01:00)"},
{name: "Argentina", code: "AR", gmt: "(UTC-03:00)"},
{name: "Armenia", code: "AM", gmt: "(UTC+04:00)"},
{name: "Australia", code: "AU", gmt: "(UTC+11:00)"},
{name: "Austria", code: "AT", gmt: "(UTC+01:00)"},
{name: "Azerbaijan", code: "AZ", gmt: "(UTC+04:00)"},
{name: "Bahrain", code: "BH", gmt: "(UTC+03:00)"},
{name: "Bangladesh", code: "BD", gmt: "(UTC+06:00)"},
{name: "Belarus", code: "BY", gmt: "(UTC+03:00)"},
{name: "Belgium", code: "BE", gmt: "(UTC+01:00)"},
{name: "Belize", code: "BZ", gmt: "(UTC-06:00)"},
{name: "Bhutan", code: "BT", gmt: "(UTC+06:00)"},
{name: "Bolivia", code: "BO", gmt: "(UTC-04:00)"},
{name: "Bosnia and Herzegovina", code: "BA", gmt: "(UTC+01:00)"},
{name: "Botswana", code: "BW", gmt: "(UTC+02:00)"},
{name: "Brazil", code: "BR", gmt: "(UTC-02:00)"},
{name: "Brunei", code: "BN", gmt: "(UTC+08:00)"},
{name: "Bulgaria", code: "BG", gmt: "(UTC+02:00)"},
{name: "Cambodia", code: "KH", gmt: "(UTC+07:00)"},
{name: "Cameroon", code: "CM", gmt: "(UTC+01:00)"},
{name: "Canada", code: "CA", gmt: "(UTC-03:30)"},
{name: "Chile", code: "CL", gmt: "(UTC-04:00)"},
{name: "China", code: "CN", gmt: "(UTC+08:00)"},
{name: "Colombia", code: "CO", gmt: "(UTC-05:00)"},
{name: "Congo (DRC)", code: "CD", gmt: "(UTC+01:00)"},
{name: "Costa Rica", code: "CR", gmt: "(UTC-06:00)"},
{name: "Côte d’Ivoire", code: "CI", gmt: "(UTC+00:00)"},
{name: "Croatia", code: "HR", gmt: "(UTC+01:00)"},
{name: "Cuba", code: "CU", gmt: "(UTC-05:00)"},
{name: "Czech Republic", code: "CZ", gmt: "(UTC+01:00)"},
{name: "Denmark", code: "DK", gmt: "(UTC+01:00)"},
{name: "Djibouti", code: "DJ", gmt: "(UTC+03:00)"},
{name: "Dominican Republic", code: "DO", gmt: "(UTC-04:00)"},
{name: "Ecuador", code: "EC", gmt: "(UTC-05:00)"},
{name: "Egypt", code: "EG", gmt: "(UTC+02:00)"},
{name: "El Salvador", code: "SV", gmt: "(UTC-06:00)"},
{name: "Eritrea", code: "ER", gmt: "(UTC+03:00)"},
{name: "Estonia", code: "EE", gmt: "(UTC+02:00)"},
{name: "Ethiopia", code: "ET", gmt: "(UTC+03:00)"},
{name: "Faroe Islands", code: "FO", gmt: "(UTC+00:00)"},
{name: "Finland", code: "FI", gmt: "(UTC+02:00)"},
{name: "France", code: "FR", gmt: "(UTC+01:00)"},
{name: "Georgia", code: "GE", gmt: "(UTC+04:00)"},
{name: "Germany", code: "DE", gmt: "(UTC+01:00)"},
{name: "Greece", code: "GR", gmt: "(UTC+02:00)"},
{name: "Greenland", code: "GL", gmt: "(UTC-03:00)"},
{name: "Guatemala", code: "GT", gmt: "(UTC-06:00)"},
{name: "Haiti", code: "HT", gmt: "(UTC-05:00)"},
{name: "Honduras", code: "HN", gmt: "(UTC-06:00)"},
{name: "Hong Kong SAR", code: "HK", gmt: "(UTC+08:00)"},
{name: "Hungary", code: "HU", gmt: "(UTC+01:00)"},
{name: "Iceland", code: "IS", gmt: "(UTC+00:00)"},
{name: "India", code: "IN", gmt: "(UTC+05:30)"},
{name: "Indonesia", code: "ID", gmt: "(UTC+07:00)"},
{name: "Iran", code: "IR", gmt: "(UTC+03:30)"},
{name: "Iraq", code: "IQ", gmt: "(UTC+03:00)"},
{name: "Ireland", code: "IE", gmt: "(UTC+00:00)"},
{name: "Israel", code: "IL", gmt: "(UTC+02:00)"},
{name: "Italy", code: "IT", gmt: "(UTC+01:00)"},
{name: "Jamaica", code: "JM", gmt: "(UTC-05:00)"},
{name: "Japan", code: "JP", gmt: "(UTC+09:00)"},
{name: "Jordan", code: "JO", gmt: "(UTC+02:00)"},
{name: "Kazakhstan", code: "KZ", gmt: "(UTC+06:00)"},
{name: "Kenya", code: "KE", gmt: "(UTC+03:00)"},
{name: "Korea", code: "KR", gmt: "(UTC+09:00)"},
{name: "Kuwait", code: "KW", gmt: "(UTC+03:00)"},
{name: "Kyrgyzstan", code: "KG", gmt: "(UTC+06:00)"},
{name: "Laos", code: "LA", gmt: "(UTC+07:00)"},
{name: "Latvia", code: "LV", gmt: "(UTC+02:00)"},
{name: "Lebanon", code: "LB", gmt: "(UTC+02:00)"},
{name: "Libya", code: "LY", gmt: "(UTC+02:00)"},
{name: "Liechtenstein", code: "LI", gmt: "(UTC+01:00)"},
{name: "Lithuania", code: "LT", gmt: "(UTC+02:00)"},
{name: "Luxembourg", code: "LU", gmt: "(UTC+01:00)"},
{name: "Macao SAR", code: "MO", gmt: "(UTC+08:00)"},
{name: "Macedonia, FYRO", code: "MK", gmt: "(UTC+01:00)"},
{name: "Malaysia", code: "MY", gmt: "(UTC+08:00)"},
{name: "Maldives", code: "MV", gmt: "(UTC+05:00)"},
{name: "Mali", code: "ML", gmt: "(UTC+00:00)"},
{name: "Malta", code: "MT", gmt: "(UTC+01:00)"},
{name: "Mexico", code: "MX", gmt: "(UTC-06:00)"},
{name: "Moldova", code: "MD", gmt: "(UTC+02:00)"},
{name: "Monaco", code: "MC", gmt: "(UTC+01:00)"},
{name: "Mongolia", code: "MN", gmt: "(UTC+08:00)"},
{name: "Montenegro", code: "ME", gmt: "(UTC+01:00)"},
{name: "Morocco", code: "MA", gmt: "(UTC+00:00)"},
{name: "Myanmar", code: "MM", gmt: "(UTC+06:30)"},
{name: "Nepal", code: "NP", gmt: "(UTC+05:45)"},
{name: "Netherlands", code: "NL", gmt: "(UTC+01:00)"},
{name: "New Zealand", code: "NZ", gmt: "(UTC+12:00)"},
{name: "Nicaragua", code: "NI", gmt: "(UTC-06:00)"},
{name: "Nigeria", code: "NG", gmt: "(UTC+01:00)"},
{name: "Norway", code: "NO", gmt: "(UTC+01:00)"},
{name: "Oman", code: "OM", gmt: "(UTC+04:00)"},
{name: "Pakistan", code: "PK", gmt: "(UTC+05:00)"},
{name: "Panama", code: "PA", gmt: "(UTC-05:00)"},
{name: "Paraguay", code: "PY", gmt: "(UTC-04:00)"},
{name: "Peru", code: "PE", gmt: "(UTC-05:00)"},
{name: "Philippines", code: "PH", gmt: "(UTC+08:00)"},
{name: "Poland", code: "PL", gmt: "(UTC+01:00)"},
{name: "Portugal", code: "PT", gmt: "(UTC+00:00)"},
{name: "Puerto Rico", code: "PR", gmt: "(UTC-04:00)"},
{name: "Qatar", code: "QA", gmt: "(UTC+03:00)"},
{name: "Réunion", code: "RE", gmt: "(UTC+04:00)"},
{name: "Romania", code: "RO", gmt: "(UTC+02:00)"},
{name: "Russia", code: "RU", gmt: "(UTC+02:00)"},
{name: "Rwanda", code: "RW", gmt: "(UTC+02:00)"},
{name: "Saudi Arabia", code: "SA", gmt: "(UTC+03:00)"},
{name: "Senegal", code: "SN", gmt: "(UTC+00:00)"},
{name: "Serbia", code: "RS", gmt: "(UTC+01:00)"},
{name: "Singapore", code: "SG", gmt: "(UTC+08:00)"},
{name: "Slovakia", code: "SK", gmt: "(UTC+01:00)"},
{name: "Slovenia", code: "SI", gmt: "(UTC+01:00)"},
{name: "Somalia", code: "SO", gmt: "(UTC+03:00)"},
{name: "South Africa", code: "ZA", gmt: "(UTC+02:00)"},
{name: "Spain", code: "ES", gmt: "(UTC+01:00)"},
{name: "Sri Lanka", code: "LK", gmt: "(UTC+05:30)"},
{name: "Sweden", code: "SE", gmt: "(UTC+01:00)"},
{name: "Switzerland", code: "CH", gmt: "(UTC+01:00)"},
{name: "Syria", code: "SY", gmt: "(UTC+02:00)"},
{name: "Taiwan", code: "TW", gmt: "(UTC+08:00)"},
{name: "Tajikistan", code: "TJ", gmt: "(UTC+05:00)"},
{name: "Thailand", code: "TH", gmt: "(UTC+07:00)"},
{name: "Trinidad and Tobago", code: "TT", gmt: "(UTC-04:00)"},
{name: "Tunisia", code: "TN", gmt: "(UTC+01:00)"},
{name: "Turkey", code: "TR", gmt: "(UTC+02:00)"},
{name: "Turkmenistan", code: "TM", gmt: "(UTC+05:00)"},
{name: "Ukraine", code: "UA", gmt: "(UTC+02:00)"},
{name: "United Arab Emirates", code: "AE", gmt: "(UTC+04:00)"},
{name: "United Kingdom", code: "GB", gmt: "(UTC+00:00)"},
{name: "United States", code: "US", gmt: "(UTC-05:00)"},
{name: "Uruguay", code: "UY", gmt: "(UTC-03:00)"},
{name: "Uzbekistan", code: "UZ", gmt: "(UTC+05:00)"},
{name: "Venezuela", code: "VE", gmt: "(UTC-04:00)"},
{name: "Vietnam", code: "VN", gmt: "(UTC+07:00)"},
{name: "Yemen", code: "YE", gmt: "(UTC+03:00)"},
{name: "Zimbabwe", code: "ZW", gmt: "(UTC+02:00)"}
]
[
{name: "Afghanistan", code: "AF", gmt: "+04:30"},
{name: "Albania", code: "AL", gmt: "+01:00"},
{name: "Algeria", code: "DZ", gmt: "+01:00"},
{name: "Argentina", code: "AR", gmt: "-03:00"},
{name: "Armenia", code: "AM", gmt: "+04:00"},
{name: "Australia", code: "AU", gmt: "+11:00"},
{name: "Austria", code: "AT", gmt: "+01:00"},
{name: "Azerbaijan", code: "AZ", gmt: "+04:00"},
{name: "Bahrain", code: "BH", gmt: "+03:00"},
{name: "Bangladesh", code: "BD", gmt: "+06:00"},
{name: "Belarus", code: "BY", gmt: "+03:00"},
{name: "Belgium", code: "BE", gmt: "+01:00"},
{name: "Belize", code: "BZ", gmt: "-06:00"},
{name: "Bhutan", code: "BT", gmt: "+06:00"},
{name: "Bolivia", code: "BO", gmt: "-04:00"},
{name: "Bosnia and Herzegovina", code: "BA", gmt: "+01:00"},
{name: "Botswana", code: "BW", gmt: "+02:00"},
{name: "Brazil", code: "BR", gmt: "-02:00"},
{name: "Brunei", code: "BN", gmt: "+08:00"},
{name: "Bulgaria", code: "BG", gmt: "+02:00"},
{name: "Cambodia", code: "KH", gmt: "+07:00"},
{name: "Cameroon", code: "CM", gmt: "+01:00"},
{name: "Canada", code: "CA", gmt: "-03:30"},
{name: "Chile", code: "CL", gmt: "-04:00"},
{name: "China", code: "CN", gmt: "+08:00"},
{name: "Colombia", code: "CO", gmt: "-05:00"},
{name: "Congo (DRC)", code: "CD", gmt: "+01:00"},
{name: "Costa Rica", code: "CR", gmt: "-06:00"},
{name: "Côte d’Ivoire", code: "CI", gmt: "+00:00"},
{name: "Croatia", code: "HR", gmt: "+01:00"},
{name: "Cuba", code: "CU", gmt: "-05:00"},
{name: "Czech Republic", code: "CZ", gmt: "+01:00"},
{name: "Denmark", code: "DK", gmt: "+01:00"},
{name: "Djibouti", code: "DJ", gmt: "+03:00"},
{name: "Dominican Republic", code: "DO", gmt: "-04:00"},
{name: "Ecuador", code: "EC", gmt: "-05:00"},
{name: "Egypt", code: "EG", gmt: "+02:00"},
{name: "El Salvador", code: "SV", gmt: "-06:00"},
{name: "Eritrea", code: "ER", gmt: "+03:00"},
{name: "Estonia", code: "EE", gmt: "+02:00"},
{name: "Ethiopia", code: "ET", gmt: "+03:00"},
{name: "Faroe Islands", code: "FO", gmt: "+00:00"},
{name: "Finland", code: "FI", gmt: "+02:00"},
{name: "France", code: "FR", gmt: "+01:00"},
{name: "Georgia", code: "GE", gmt: "+04:00"},
{name: "Germany", code: "DE", gmt: "+01:00"},
{name: "Greece", code: "GR", gmt: "+02:00"},
{name: "Greenland", code: "GL", gmt: "-03:00"},
{name: "Guatemala", code: "GT", gmt: "-06:00"},
{name: "Haiti", code: "HT", gmt: "-05:00"},
{name: "Honduras", code: "HN", gmt: "-06:00"},
{name: "Hong Kong SAR", code: "HK", gmt: "+08:00"},
{name: "Hungary", code: "HU", gmt: "+01:00"},
{name: "Iceland", code: "IS", gmt: "+00:00"},
{name: "India", code: "IN", gmt: "+05:30"},
{name: "Indonesia", code: "ID", gmt: "+07:00"},
{name: "Iran", code: "IR", gmt: "+03:30"},
{name: "Iraq", code: "IQ", gmt: "+03:00"},
{name: "Ireland", code: "IE", gmt: "+00:00"},
{name: "Israel", code: "IL", gmt: "+02:00"},
{name: "Italy", code: "IT", gmt: "+01:00"},
{name: "Jamaica", code: "JM", gmt: "-05:00"},
{name: "Japan", code: "JP", gmt: "+09:00"},
{name: "Jordan", code: "JO", gmt: "+02:00"},
{name: "Kazakhstan", code: "KZ", gmt: "+06:00"},
{name: "Kenya", code: "KE", gmt: "+03:00"},
{name: "Korea", code: "KR", gmt: "+09:00"},
{name: "Kuwait", code: "KW", gmt: "+03:00"},
{name: "Kyrgyzstan", code: "KG", gmt: "+06:00"},
{name: "Laos", code: "LA", gmt: "+07:00"},
{name: "Latvia", code: "LV", gmt: "+02:00"},
{name: "Lebanon", code: "LB", gmt: "+02:00"},
{name: "Libya", code: "LY", gmt: "+02:00"},
{name: "Liechtenstein", code: "LI", gmt: "+01:00"},
{name: "Lithuania", code: "LT", gmt: "+02:00"},
{name: "Luxembourg", code: "LU", gmt: "+01:00"},
{name: "Macao SAR", code: "MO", gmt: "+08:00"},
{name: "Macedonia, FYRO", code: "MK", gmt: "+01:00"},
{name: "Malaysia", code: "MY", gmt: "+08:00"},
{name: "Maldives", code: "MV", gmt: "+05:00"},
{name: "Mali", code: "ML", gmt: "+00:00"},
{name: "Malta", code: "MT", gmt: "+01:00"},
{name: "Mexico", code: "MX", gmt: "-06:00"},
{name: "Moldova", code: "MD", gmt: "+02:00"},
{name: "Monaco", code: "MC", gmt: "+01:00"},
{name: "Mongolia", code: "MN", gmt: "+08:00"},
{name: "Montenegro", code: "ME", gmt: "+01:00"},
{name: "Morocco", code: "MA", gmt: "+00:00"},
{name: "Myanmar", code: "MM", gmt: "+06:30"},
{name: "Nepal", code: "NP", gmt: "+05:45"},
{name: "Netherlands", code: "NL", gmt: "+01:00"},
{name: "New Zealand", code: "NZ", gmt: "+12:00"},
{name: "Nicaragua", code: "NI", gmt: "-06:00"},
{name: "Nigeria", code: "NG", gmt: "+01:00"},
{name: "Norway", code: "NO", gmt: "+01:00"},
{name: "Oman", code: "OM", gmt: "+04:00"},
{name: "Pakistan", code: "PK", gmt: "+05:00"},
{name: "Panama", code: "PA", gmt: "-05:00"},
{name: "Paraguay", code: "PY", gmt: "-04:00"},
{name: "Peru", code: "PE", gmt: "-05:00"},
{name: "Philippines", code: "PH", gmt: "+08:00"},
{name: "Poland", code: "PL", gmt: "+01:00"},
{name: "Portugal", code: "PT", gmt: "+00:00"},
{name: "Puerto Rico", code: "PR", gmt: "-04:00"},
{name: "Qatar", code: "QA", gmt: "+03:00"},
{name: "Réunion", code: "RE", gmt: "+04:00"},
{name: "Romania", code: "RO", gmt: "+02:00"},
{name: "Russia", code: "RU", gmt: "+02:00"},
{name: "Rwanda", code: "RW", gmt: "+02:00"},
{name: "Saudi Arabia", code: "SA", gmt: "+03:00"},
{name: "Senegal", code: "SN", gmt: "+00:00"},
{name: "Serbia", code: "RS", gmt: "+01:00"},
{name: "Singapore", code: "SG", gmt: "+08:00"},
{name: "Slovakia", code: "SK", gmt: "+01:00"},
{name: "Slovenia", code: "SI", gmt: "+01:00"},
{name: "Somalia", code: "SO", gmt: "+03:00"},
{name: "South Africa", code: "ZA", gmt: "+02:00"},
{name: "Spain", code: "ES", gmt: "+01:00"},
{name: "Sri Lanka", code: "LK", gmt: "+05:30"},
{name: "Sweden", code: "SE", gmt: "+01:00"},
{name: "Switzerland", code: "CH", gmt: "+01:00"},
{name: "Syria", code: "SY", gmt: "+02:00"},
{name: "Taiwan", code: "TW", gmt: "+08:00"},
{name: "Tajikistan", code: "TJ", gmt: "+05:00"},
{name: "Thailand", code: "TH", gmt: "+07:00"},
{name: "Trinidad and Tobago", code: "TT", gmt: "-04:00"},
{name: "Tunisia", code: "TN", gmt: "+01:00"},
{name: "Turkey", code: "TR", gmt: "+02:00"},
{name: "Turkmenistan", code: "TM", gmt: "+05:00"},
{name: "Ukraine", code: "UA", gmt: "+02:00"},
{name: "United Arab Emirates", code: "AE", gmt: "+04:00"},
{name: "United Kingdom", code: "GB", gmt: "+00:00"},
{name: "United States", code: "US", gmt: "-05:00"},
{name: "Uruguay", code: "UY", gmt: "-03:00"},
{name: "Uzbekistan", code: "UZ", gmt: "+05:00"},
{name: "Venezuela", code: "VE", gmt: "-04:00"},
{name: "Vietnam", code: "VN", gmt: "+07:00"},
{name: "Yemen", code: "YE", gmt: "+03:00"},
{name: "Zimbabwe", code: "ZW", gmt: "+02:00"}
]
If a commercial solution is acceptable, you could check out the World Time Zone Database.
Ruby on Rails uses the following mapping for timezones: http://apidock.com/rails/TimeZone
Related
I am working with the Spotify API and having trouble with the data model due to the JSON data being more complex than any other data I've seen via tutorials or courses. How would I make my struct for the "items" in this JSON data? I understand a majority of the parameters, for example, "album_group": String and "available_markets": [String] but I don't understand what to do with "artists", "external_urls", and "images". Any help would be appreciated.
Below is the first "item" from the data.
Side Note When I'm creating my struct do I have to include EVERY parameter shown below for my API call to work?
{
"href": "https://api.spotify.com/v1/artists/3qiHUAX7zY4Qnjx8TNUzVx/albums?offset=0&limit=20&include_groups=album,single,compilation,appears_on&locale=en-US,en;q=0.9",
"items": [
{
"album_group": "album",
"album_type": "album",
"artists": [
{
"external_urls": {
"spotify": "https://open.spotify.com/artist/3qiHUAX7zY4Qnjx8TNUzVx"
},
"href": "https://api.spotify.com/v1/artists/3qiHUAX7zY4Qnjx8TNUzVx",
"id": "3qiHUAX7zY4Qnjx8TNUzVx",
"name": "Yeat",
"type": "artist",
"uri": "spotify:artist:3qiHUAX7zY4Qnjx8TNUzVx"
}
],
"available_markets": [
"AD",
"AE",
"AG",
"AL",
"AM",
"AO",
"AR",
"AT",
"AU",
"AZ",
"BA",
"BB",
"BD",
"BE",
"BF",
"BG",
"BH",
"BI",
"BJ",
"BN",
"BO",
"BR",
"BS",
"BT",
"BW",
"BY",
"BZ",
"CA",
"CD",
"CG",
"CH",
"CI",
"CL",
"CM",
"CO",
"CR",
"CV",
"CY",
"CZ",
"DE",
"DJ",
"DK",
"DM",
"DO",
"DZ",
"EC",
"EE",
"EG",
"ES",
"FI",
"FJ",
"FM",
"FR",
"GA",
"GB",
"GD",
"GE",
"GH",
"GM",
"GN",
"GQ",
"GR",
"GT",
"GW",
"GY",
"HK",
"HN",
"HR",
"HT",
"HU",
"ID",
"IE",
"IL",
"IN",
"IQ",
"IS",
"IT",
"JM",
"JO",
"JP",
"KE",
"KG",
"KH",
"KI",
"KM",
"KN",
"KR",
"KW",
"KZ",
"LA",
"LB",
"LC",
"LI",
"LK",
"LR",
"LS",
"LT",
"LU",
"LV",
"LY",
"MA",
"MC",
"MD",
"ME",
"MG",
"MH",
"MK",
"ML",
"MN",
"MO",
"MR",
"MT",
"MU",
"MV",
"MW",
"MX",
"MY",
"MZ",
"NA",
"NE",
"NG",
"NI",
"NL",
"NO",
"NP",
"NR",
"NZ",
"OM",
"PA",
"PE",
"PG",
"PH",
"PK",
"PL",
"PS",
"PT",
"PW",
"PY",
"QA",
"RO",
"RS",
"RU",
"RW",
"SA",
"SB",
"SC",
"SE",
"SG",
"SI",
"SK",
"SL",
"SM",
"SN",
"SR",
"ST",
"SV",
"SZ",
"TD",
"TG",
"TH",
"TJ",
"TL",
"TN",
"TO",
"TR",
"TT",
"TV",
"TW",
"TZ",
"UA",
"UG",
"US",
"UY",
"UZ",
"VC",
"VE",
"VN",
"VU",
"WS",
"XK",
"ZA",
"ZM",
"ZW"
],
"external_urls": {
"spotify": "https://open.spotify.com/album/1x55Z0fYARLdeJVjG2UESs"
},
"href": "https://api.spotify.com/v1/albums/1x55Z0fYARLdeJVjG2UESs",
"id": "1x55Z0fYARLdeJVjG2UESs",
"images": [
{
"height": 640,
"url": "https://i.scdn.co/image/ab67616d0000b273b20fdc3ee4c262693cfdf005",
"width": 640
},
{
"height": 300,
"url": "https://i.scdn.co/image/ab67616d00001e02b20fdc3ee4c262693cfdf005",
"width": 300
},
{
"height": 64,
"url": "https://i.scdn.co/image/ab67616d00004851b20fdc3ee4c262693cfdf005",
"width": 64
}
],
"name": "Up 2 Më",
"release_date": "2021-09-10",
"release_date_precision": "day",
"total_tracks": 22,
"type": "album",
"uri": "spotify:album:1x55Z0fYARLdeJVjG2UESs"
}
]
}
Good rule of thumb is, that you need a separate Decodable object for every JSON object (marked with {}) when working with such API.
You can nest Decodable structs. Just don't forget that here, ExternalUrl has to be Decodable too, otherwise you will get an error
struct SpotifyItem: Decodable {
// ...
let artists: [Artist]
let images: [SpotifyImage]
// ...
}
struct Artist: Decodable {
let external_urls: ExternalUrl
let href: String
let id: String
// ...
}
struct ExternalUrl: Decodable {
let spotify: String
}
struct SpotifyImage: Decodable {
let url: String
let height: Int
let width: Int
}
Side Note Answer: I would advise you to do so. It seems like there are ways to decode JSON elements into swift dictionary, but it goes against the type safety that you are trying to achieve. You are parsing JSON into Decodable structs precisely because you want to know ahead of time what are you dealing with.
Don't forget you can still do optional attributes, for example you could have
struct ExternalUrl: Decodable {
let spotify: String
let instagram: String?
}
In that case, if instagram is not present, it will be set to nil. My advice would be follow this more modern and safe way of doing things. You can of course parse the entire JSON into a huge [String: Any] object, but you will have to write out everything you want to access anyway. Plus there will be a LOT of type casting and checks, which Codable does for you.
I want to add " 5 " in my arrays in every 3rd position
var myList: [String] = ["U.S", "Spain", "China", "Brazil", "India" , "Canada", "Germany", "UK", "Dubai", "Russia", "Japan", "Italy", "France", "Australia", "Thailand", "Mexico"]
var i = 0
for name in 0...myList.count {
i = i + 1
if i % 3 == 0 {
myList.insert("\(5)", at: i )
}
}
print("\(myList)")
OutPut is:
["U.S", "Spain", "China", "5", "Brazil", "India", "5", "Canada", "Germany", "5", "UK", "Dubai", "5", "Russia", "Japan", "5", "Italy", "France", "Australia", "Thailand", "Mexico"]
but after 16 position in array , I am not able to put all 5 in my arrays because of arrays that is myList have total 16 counts ....so how I can able to put 5 in my Arrays properly
The problem there is that you are mutating the array (changing its elements while iterating it), so what you actually need to do is to insert your elements in reverse order. Try like this:
var myList = ["U.S", "Spain", "China", "Brazil", "India", "Canada", "Germany", "UK", "Dubai", "Russia", "Japan", "Italy", "France", "Australia", "Thailand", "Mexico" ]
for index in myList.indices.dropFirst().reversed() where index % 3 == 0 {
myList.insert("5", at: index)
}
print(myList) // "["U.S", "Spain", "China", "5", "Brazil", "India", "Canada", "5", "Germany", "UK", "Dubai", "5", "Russia", "Japan", "Italy", "5", "France", "Australia", "Thailand", "5", "Mexico"]\n"
Ruby 2.2.3, Rails 4.2.1
I have a large number of arrays of strings that I define as constants for use throughout an application. They are various sets of ISO country codes, language codes, that sort of thing, so two to four characters, numbered in the hundreds of unique values each.
The different arrays are collections of these, so NORTH_AMERICA_COUNTRY_CODES might be an array of a dozen of so country codes, AFRICA_COUNTRY_CODES might be an array of around 60. Many of them overlap (various versions of the Commonwealth countries, for example).
The arrays are used in comparison with other arbitrary arrays of country codes for logic such as "Subtract this list of countries from Africa".
So I'm wondering whether, when I generate these constants, I ought to freeze the strings within the arrays, so instead of:
WORLD_COUNTRIES = Countries.pluck(:country_code).freeze
... maybe ...
WORLD_COUNTRIES = Countries.pluck(:country_code).map{|c| c.freeze}.freeze
Is there a way of quantifying the potential benefits?
I considered using arrays of symbols instead of arrays of strings, but the arbitrary arrays that these are used with are stored in PostgreSQL text arrays, and it seems like I'd need to serialise those columns instead, or maybe override the getter and setter methods to change the values between arrays of strings and arrays of symbols. Ugh.
Edit
Testing results, in which I've attempted to benchmark three situations:
Comparing a frozen array of unfrozen strings with an unfrozen array of unfrozen strings
Comparing a frozen array of frozen strings with an unfrozen array of unfrozen strings
Comparing a frozen array of symbols with an unfrozen array of symbols (in case I bit the bullet and went all symbolic on this).
Any thoughts on methodology or interpretation gratefully received. I'm not sure whether the similarity in results between the first two indicates that they are in all respects the same, but I'd be keen on anything that can directly point to differences in memory allocation.
Script:
require 'benchmark'
country_list = ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
FROZEN_ARRAY = country_list.dup.freeze
puts FROZEN_ARRAY.size
FROZEN_ARRAY_AND_STRINGS = country_list.dup.map{|x| x.freeze}.freeze
FROZEN_ARRAY_AND_SYMBOLS = country_list.dup.map{|x| x.to_sym}.freeze
comp_s = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA)
comp_sym = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA).map{|x| x.to_sym}
Benchmark.bm do |x|
x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
end
Benchmark.bmbm do |x|
x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
end
Result:
2.2.3 :001 > require 'benchmark'
=> false
2.2.3 :002 >
2.2.3 :003 > country_list = ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :004 > FROZEN_ARRAY = country_list.dup.freeze
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :005 > puts FROZEN_ARRAY.size
252
=> nil
2.2.3 :006 > FROZEN_ARRAY_AND_STRINGS = country_list.dup.map{|x| x.freeze}.freeze
=> ["AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", "AR", "AS", "AT", "AU", "AW", "AX", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", "BI", "BJ", "BL", "BM", "BN", "BO", "BQ", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CS", "CU", "CV", "CW", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "GA", "GB", "GD", "GE", "GF", "GG", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IM", "IN", "IO", "IQ", "IR", "IS", "IT", "JE", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", "LT", "LU", "LV", "LY", "MA", "MC", "MD", "ME", "MF", "MG", "MH", "MK", "ML", "MM", "MN", "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", "QA", "RE", "RO", "RS", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "SS", "ST", "SV", "SX", "SY", "SZ", "TC", "TD", "TF", "TG", "TH", "TJ", "TK", "TL", "TM", "TN", "TO", "TR", "TT", "TV", "TW", "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", "VU", "WF", "WS", "YE", "YT", "YU", "ZA", "ZM", "ZW"]
2.2.3 :007 > FROZEN_ARRAY_AND_SYMBOLS = country_list.dup.map{|x| x.to_sym}.freeze
=> [:AD, :AE, :AF, :AG, :AI, :AL, :AM, :AN, :AO, :AQ, :AR, :AS, :AT, :AU, :AW, :AX, :AZ, :BA, :BB, :BD, :BE, :BF, :BG, :BH, :BI, :BJ, :BL, :BM, :BN, :BO, :BQ, :BR, :BS, :BT, :BV, :BW, :BY, :BZ, :CA, :CC, :CD, :CF, :CG, :CH, :CI, :CK, :CL, :CM, :CN, :CO, :CR, :CS, :CU, :CV, :CW, :CX, :CY, :CZ, :DE, :DJ, :DK, :DM, :DO, :DZ, :EC, :EE, :EG, :EH, :ER, :ES, :ET, :FI, :FJ, :FK, :FM, :FO, :FR, :GA, :GB, :GD, :GE, :GF, :GG, :GH, :GI, :GL, :GM, :GN, :GP, :GQ, :GR, :GS, :GT, :GU, :GW, :GY, :HK, :HM, :HN, :HR, :HT, :HU, :ID, :IE, :IL, :IM, :IN, :IO, :IQ, :IR, :IS, :IT, :JE, :JM, :JO, :JP, :KE, :KG, :KH, :KI, :KM, :KN, :KP, :KR, :KW, :KY, :KZ, :LA, :LB, :LC, :LI, :LK, :LR, :LS, :LT, :LU, :LV, :LY, :MA, :MC, :MD, :ME, :MF, :MG, :MH, :MK, :ML, :MM, :MN, :MO, :MP, :MQ, :MR, :MS, :MT, :MU, :MV, :MW, :MX, :MY, :MZ, :NA, :NC, :NE, :NF, :NG, :NI, :NL, :NO, :NP, :NR, :NU, :NZ, :OM, :PA, :PE, :PF, :PG, :PH, :PK, :PL, :PM, :PN, :PR, :PS, :PT, :PW, :PY, :QA, :RE, :RO, :RS, :RU, :RW, :SA, :SB, :SC, :SD, :SE, :SG, :SH, :SI, :SJ, :SK, :SL, :SM, :SN, :SO, :SR, :SS, :ST, :SV, :SX, :SY, :SZ, :TC, :TD, :TF, :TG, :TH, :TJ, :TK, :TL, :TM, :TN, :TO, :TR, :TT, :TV, :TW, :TZ, :UA, :UG, :UM, :US, :UY, :UZ, :VA, :VC, :VE, :VG, :VI, :VN, :VU, :WF, :WS, :YE, :YT, :YU, :ZA, :ZM, :ZW]
2.2.3 :008 > comp_s = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA)
=> ["AD", "AT", "BE", "CY", "EE", "FI", "FR", "DE", "ES", "GR", "IE", "IT", "LU", "LV", "MC", "ME", "MT", "NL", "PT", "SI", "SK", "SM", "VA"]
2.2.3 :009 > comp_sym = %w(AD AT BE CY EE FI FR DE ES GR IE IT LU LV MC ME MT NL PT SI SK SM VA).map{|x| x.to_sym}
=> [:AD, :AT, :BE, :CY, :EE, :FI, :FR, :DE, :ES, :GR, :IE, :IT, :LU, :LV, :MC, :ME, :MT, :NL, :PT, :SI, :SK, :SM, :VA]
2.2.3 :010 >
2.2.3 :011 >
2.2.3 :012 > Benchmark.bm do |x|
2.2.3 :013 > x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
2.2.3 :014?> x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
2.2.3 :015?> x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
2.2.3 :016?> end
user system total real
frozen string 0.190000 0.000000 0.190000 ( 0.194141)
unfrozen string 0.170000 0.010000 0.180000 ( 0.174675)
symbols 0.080000 0.000000 0.080000 ( 0.081507)
=> [#<Benchmark::Tms:0x007f810c3aca70 #label="frozen string", #real=0.1941408810671419, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.1899999999999995, #total=0.1899999999999995>, #<Benchmark::Tms:0x007f810c82b538 #label="unfrozen string", #real=0.1746752569451928, #cstime=0.0, #cutime=0.0, #stime=0.010000000000000009, #utime=0.16999999999999993, #total=0.17999999999999994>, #<Benchmark::Tms:0x007f810af2cfa0 #label="symbols", #real=0.08150708093307912, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.08000000000000007, #total=0.08000000000000007>]
2.2.3 :017 >
2.2.3 :018 >
2.2.3 :019 > Benchmark.bmbm do |x|
2.2.3 :020 > x.report("frozen string" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_STRINGS & comp_s.dup) }}
2.2.3 :021?> x.report("unfrozen string") { 10000.times {|i| c = (FROZEN_ARRAY & comp_s.dup) }}
2.2.3 :022?> x.report("symbols" ) { 10000.times {|i| c = (FROZEN_ARRAY_AND_SYMBOLS & comp_sym.dup) }}
2.2.3 :023?> end
Rehearsal ---------------------------------------------------
frozen string 0.180000 0.000000 0.180000 ( 0.183846)
unfrozen string 0.200000 0.000000 0.200000 ( 0.196311)
symbols 0.080000 0.000000 0.080000 ( 0.082794)
------------------------------------------ total: 0.460000sec
user system total real
frozen string 0.160000 0.000000 0.160000 ( 0.167051)
unfrozen string 0.170000 0.000000 0.170000 ( 0.171601)
symbols 0.080000 0.000000 0.080000 ( 0.078746)
=> [#<Benchmark::Tms:0x007f811022a388 #label="frozen string", #real=0.1670510449912399, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.16000000000000014, #total=0.16000000000000014>, #<Benchmark::Tms:0x007f811022a4c8 #label="unfrozen string", #real=0.17160122003406286, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.16999999999999993, #total=0.16999999999999993>, #<Benchmark::Tms:0x007f8108eb1c58 #label="symbols", #real=0.07874645793344826, #cstime=0.0, #cutime=0.0, #stime=0.0, #utime=0.08000000000000007, #total=0.08000000000000007>]
2.2.3 :024 >
2.2.3 :025 >
2.2.3 :026 >
Since you're dealing with a small number of values, and since the performance benefits of symbols are evident from your testing, just go with symbols.
BTW, you can use map(&:to_sym) instead of map {|x| x.to_sym}.
I'm working on a project
I need to send the selected phone number (which user selected already from phone contacts list) to the sever with format :
international-code-without-zeros-or-plus_the-number
so I need to handle many cases : number without international code , number with zeros , number with plus , number with two zeros ..etc
the problem is when I have a local phone number unprecedented by country phone code,I could get the current country name (country name code) if the device has a valid sim card via this code
let networkInfo: CTTelephonyNetworkInfo = CTTelephonyNetworkInfo()
let ar = networkInfo.subscriberCellularProvider
if ar != nil {
if let mcc = ar.mobileCountryCode {
myInformation.countryCode = mcc
}
then how can I get the country phone code??
class func getCountryPhonceCode (_ country : String) -> String
{
var countryDictionary = ["AF":"93",
"AL":"355",
"DZ":"213",
"AS":"1",
"AD":"376",
"AO":"244",
"AI":"1",
"AG":"1",
"AR":"54",
"AM":"374",
"AW":"297",
"AU":"61",
"AT":"43",
"AZ":"994",
"BS":"1",
"BH":"973",
"BD":"880",
"BB":"1",
"BY":"375",
"BE":"32",
"BZ":"501",
"BJ":"229",
"BM":"1",
"BT":"975",
"BA":"387",
"BW":"267",
"BR":"55",
"IO":"246",
"BG":"359",
"BF":"226",
"BI":"257",
"KH":"855",
"CM":"237",
"CA":"1",
"CV":"238",
"KY":"345",
"CF":"236",
"TD":"235",
"CL":"56",
"CN":"86",
"CX":"61",
"CO":"57",
"KM":"269",
"CG":"242",
"CK":"682",
"CR":"506",
"HR":"385",
"CU":"53",
"CY":"537",
"CZ":"420",
"DK":"45",
"DJ":"253",
"DM":"1",
"DO":"1",
"EC":"593",
"EG":"20",
"SV":"503",
"GQ":"240",
"ER":"291",
"EE":"372",
"ET":"251",
"FO":"298",
"FJ":"679",
"FI":"358",
"FR":"33",
"GF":"594",
"PF":"689",
"GA":"241",
"GM":"220",
"GE":"995",
"DE":"49",
"GH":"233",
"GI":"350",
"GR":"30",
"GL":"299",
"GD":"1",
"GP":"590",
"GU":"1",
"GT":"502",
"GN":"224",
"GW":"245",
"GY":"595",
"HT":"509",
"HN":"504",
"HU":"36",
"IS":"354",
"IN":"91",
"ID":"62",
"IQ":"964",
"IE":"353",
"IL":"972",
"IT":"39",
"JM":"1",
"JP":"81",
"JO":"962",
"KZ":"77",
"KE":"254",
"KI":"686",
"KW":"965",
"KG":"996",
"LV":"371",
"LB":"961",
"LS":"266",
"LR":"231",
"LI":"423",
"LT":"370",
"LU":"352",
"MG":"261",
"MW":"265",
"MY":"60",
"MV":"960",
"ML":"223",
"MT":"356",
"MH":"692",
"MQ":"596",
"MR":"222",
"MU":"230",
"YT":"262",
"MX":"52",
"MC":"377",
"MN":"976",
"ME":"382",
"MS":"1",
"MA":"212",
"MM":"95",
"NA":"264",
"NR":"674",
"NP":"977",
"NL":"31",
"AN":"599",
"NC":"687",
"NZ":"64",
"NI":"505",
"NE":"227",
"NG":"234",
"NU":"683",
"NF":"672",
"MP":"1",
"NO":"47",
"OM":"968",
"PK":"92",
"PW":"680",
"PA":"507",
"PG":"675",
"PY":"595",
"PE":"51",
"PH":"63",
"PL":"48",
"PT":"351",
"PR":"1",
"QA":"974",
"RO":"40",
"RW":"250",
"WS":"685",
"SM":"378",
"SA":"966",
"SN":"221",
"RS":"381",
"SC":"248",
"SL":"232",
"SG":"65",
"SK":"421",
"SI":"386",
"SB":"677",
"ZA":"27",
"GS":"500",
"ES":"34",
"LK":"94",
"SD":"249",
"SR":"597",
"SZ":"268",
"SE":"46",
"CH":"41",
"TJ":"992",
"TH":"66",
"TG":"228",
"TK":"690",
"TO":"676",
"TT":"1",
"TN":"216",
"TR":"90",
"TM":"993",
"TC":"1",
"TV":"688",
"UG":"256",
"UA":"380",
"AE":"971",
"GB":"44",
"US":"1",
"UY":"598",
"UZ":"998",
"VU":"678",
"WF":"681",
"YE":"967",
"ZM":"260",
"ZW":"263",
"BO":"591",
"BN":"673",
"CC":"61",
"CD":"243",
"CI":"225",
"FK":"500",
"GG":"44",
"VA":"379",
"HK":"852",
"IR":"98",
"IM":"44",
"JE":"44",
"KP":"850",
"KR":"82",
"LA":"856",
"LY":"218",
"MO":"853",
"MK":"389",
"FM":"691",
"MD":"373",
"MZ":"258",
"PS":"970",
"PN":"872",
"RE":"262",
"RU":"7",
"BL":"590",
"SH":"290",
"KN":"1",
"LC":"1",
"MF":"590",
"PM":"508",
"VC":"1",
"ST":"239",
"SO":"252",
"SJ":"47",
"SY":"963",
"TW":"886",
"TZ":"255",
"TL":"670",
"VE":"58",
"VN":"84",
"VG":"284",
"VI":"340"]
if let countryCode = countryDictionary[country] {
return countryCode
}
return ""
}
My suggested answer is something like brute force method !
is to list all country names and its matched country phone code in a dictionary and use searching function that gives me the matched phone code to a specific country code
func getCountryPhonceCode (country : String) -> String
{
if count(country) == 2
{
let x : [String] = ["972", "IL",
"93" , "AF",
"355", "AL",
"213", "DZ",
"1" , "AS",
"376", "AD",
"244", "AO",
"1" , "AI",
"1" , "AG",
"54" , "AR",
"374", "AM",
"297", "AW",
"61" , "AU",
"43" , "AT",
"994", "AZ",
"1" , "BS",
"973", "BH",
"880", "BD",
"1" , "BB",
"375", "BY",
"32" , "BE",
"501", "BZ",
"229", "BJ",
"1" , "BM",
"975", "BT",
"387", "BA",
"267", "BW",
"55" , "BR",
"246", "IO",
"359", "BG",
"226", "BF",
"257", "BI",
"855", "KH",
"237", "CM",
"1" , "CA",
"238", "CV",
"345", "KY",
"236", "CF",
"235", "TD",
"56", "CL",
"86", "CN",
"61", "CX",
"57", "CO",
"269", "KM",
"242", "CG",
"682", "CK",
"506", "CR",
"385", "HR",
"53" , "CU" ,
"537", "CY",
"420", "CZ",
"45" , "DK" ,
"253", "DJ",
"1" , "DM",
"1" , "DO",
"593", "EC",
"20" , "EG" ,
"503", "SV",
"240", "GQ",
"291", "ER",
"372", "EE",
"251", "ET",
"298", "FO",
"679", "FJ",
"358", "FI",
"33" , "FR",
"594", "GF",
"689", "PF",
"241", "GA",
"220", "GM",
"995", "GE",
"49" , "DE",
"233", "GH",
"350", "GI",
"30" , "GR",
"299", "GL",
"1" , "GD",
"590", "GP",
"1" , "GU",
"502", "GT",
"224", "GN",
"245", "GW",
"595", "GY",
"509", "HT",
"504", "HN",
"36" , "HU",
"354", "IS",
"91" , "IN",
"62" , "ID",
"964", "IQ",
"353", "IE",
"972", "IL",
"39" , "IT",
"1" , "JM",
"81", "JP", "962", "JO", "77", "KZ",
"254", "KE", "686", "KI", "965", "KW", "996", "KG",
"371", "LV", "961", "LB", "266", "LS", "231", "LR",
"423", "LI", "370", "LT", "352", "LU", "261", "MG",
"265", "MW", "60", "MY", "960", "MV", "223", "ML",
"356", "MT", "692", "MH", "596", "MQ", "222", "MR",
"230", "MU", "262", "YT", "52","MX", "377", "MC",
"976", "MN", "382", "ME", "1", "MS", "212", "MA",
"95", "MM", "264", "NA", "674", "NR", "977", "NP",
"31", "NL", "599", "AN", "687", "NC", "64", "NZ",
"505", "NI", "227", "NE", "234", "NG", "683", "NU",
"672", "NF", "1", "MP", "47", "NO", "968", "OM",
"92", "PK", "680", "PW", "507", "PA", "675", "PG",
"595", "PY", "51", "PE", "63", "PH", "48", "PL",
"351", "PT", "1", "PR", "974", "QA", "40", "RO",
"250", "RW", "685", "WS", "378", "SM", "966", "SA",
"221", "SN", "381", "RS", "248", "SC", "232", "SL",
"65", "SG", "421", "SK", "386", "SI", "677", "SB",
"27", "ZA", "500", "GS", "34", "ES", "94", "LK",
"249", "SD", "597", "SR", "268", "SZ", "46", "SE",
"41", "CH", "992", "TJ", "66", "TH", "228", "TG",
"690", "TK", "676", "TO", "1", "TT", "216", "TN",
"90", "TR", "993", "TM", "1", "TC", "688", "TV",
"256", "UG", "380", "UA", "971", "AE", "44", "GB",
"1", "US", "598", "UY", "998", "UZ", "678", "VU",
"681", "WF", "967", "YE", "260", "ZM", "263", "ZW",
"591", "BO", "673", "BN", "61", "CC", "243", "CD",
"225", "CI", "500", "FK", "44", "GG", "379", "VA",
"852", "HK", "98", "IR", "44", "IM", "44", "JE",
"850", "KP", "82", "KR", "856", "LA", "218", "LY",
"853", "MO", "389", "MK", "691", "FM", "373", "MD",
"258", "MZ", "970", "PS", "872", "PN", "262", "RE",
"7", "RU", "590", "BL", "290", "SH", "1", "KN",
"1", "LC", "590", "MF", "508", "PM", "1", "VC",
"239", "ST", "252", "SO", "47", "SJ",
"963","SY",
"886",
"TW", "255",
"TZ", "670",
"TL","58",
"VE","84",
"VN",
"284", "VG",
"340", "VI",
"678","VU",
"681","WF",
"685","WS",
"967","YE",
"262","YT",
"27","ZA",
"260","ZM",
"263","ZW"]
var keys = [String]()
var values = [String]()
let whitespace = NSCharacterSet.decimalDigitCharacterSet()
//let range = phrase.rangeOfCharacterFromSet(whitespace)
for i in x {
// range will be nil if no whitespace is found
if (i.rangeOfCharacterFromSet(whitespace) != nil) {
values.append(i)
}
else {
keys.append(i)
}
}
var countryCodeListDict = NSDictionary(objects: values as [String], forKeys: keys as [String])
if let t: AnyObject = countryCodeListDict[country] {
return countryCodeListDict[country] as! String
} else
{
return ""
}
}
else
{
return ""
}
}
I made help class for it and I made an example app
import Foundation
public class Countries {
// MARK: - var and let
// MARK: - functions
public static func getAllCountries() -> [Country] {
var countries = [Country]()
NSLocale.ISOCountryCodes().forEach { (isoCode) in
guard let countryName = NSLocale.currentLocale().displayNameForKey(NSLocaleCountryCode, value: isoCode) else { return }
if let countryInfo = countryInfoDictionary[isoCode] {
let phoneExtension = countryInfo["phoneExtension"] as! String
let isMain = countryInfo["isMain"] as! Bool
countries.append(Country(name: countryName, phoneExtension: phoneExtension, countryCode: isoCode, isMain: isMain))
} else {
countries.append(Country(name: countryName, phoneExtension: nil, countryCode: isoCode, isMain: nil))
}
}
return countries
}
public static func getCountriesByFirstLetter() -> [(String, [Country])] {
let countries = getAllCountries()
var countryDictionary = [String : [Country]]()
var countryFirstLetterArray = [String]()
countries.forEach { (country) in
let letterIndex = country.name.startIndex.advancedBy(0)
countryFirstLetterArray.append(String(country.name[letterIndex]))
if countryFirstLetterArray.count == 249 {
countryFirstLetterArray = Array(Set(countryFirstLetterArray))
countryFirstLetterArray.sortInPlace({ (firstString, secondString) -> Bool in
firstString < secondString
})
}
}
//
countryFirstLetterArray.forEach { (letter) in
countries.forEach({ (country) in
let letterIndex = country.name.startIndex.advancedBy(0)
let firsNameLetter = String(country.name[letterIndex])
if firsNameLetter == letter {
if var countries = countryDictionary[letter] {
countries.append(country)
countryDictionary[letter] = countries
} else {
countryDictionary[letter] = [country]
}
}
})
}
// sorting
let returnedCountries = countryDictionary.sort({$0.0 < $1.0})
return returnedCountries
}
public static func getCountriesWithPhone() -> [Country] {
var countries = getCountriesWithPhoneCode()
countries.sortInPlace({$0.name < $1.name})
return countries
}
public static func getCountriesByPhoneCode() -> [Country] {
var countries = getCountriesWithPhoneCode()
countries.sortInPlace({$0.phoneExtension! < $1.phoneExtension})
return countries
}
private static func getCountriesWithPhoneCode() -> [Country] {
let countries = getAllCountries()
var returnedCountries = [Country]()
countries.forEach { (country) in
if country.phoneExtension != nil {
returnedCountries.append(country)
}
}
return returnedCountries
}
}
extension Countries {
public static var countryInfoDictionary = ["AF" : ["phoneExtension" : "93", "isMain" : true], "AL" : ["phoneExtension" : "355", "isMain" : true], "DZ" : ["phoneExtension" : "213", "isMain" : true], "AS" : ["phoneExtension" : "1", "isMain" : false], "AD" : ["phoneExtension" : "376", "isMain" : true], "AO" :["phoneExtension" : "244", "isMain" : true], "AI" : ["phoneExtension" : "1", "isMain" : false], "AQ" : ["phoneExtension" : "672", "isMain" : true], "AG" : ["phoneExtension" : "1", "isMain" : false], "AR" : ["phoneExtension" : "54", "isMain" : true], "AM" : ["phoneExtension" : "374", "isMain" : true], "AW" : ["phoneExtension" : "297", "isMain" : true], "AU" : ["phoneExtension" : "61", "isMain" : true], "AT" : ["phoneExtension" : "43", "isMain" : true], "AZ": ["phoneExtension" : "994", "isMain" : true], "BS" : ["phoneExtension" : "1", "isMain" : false], "BH" : ["phoneExtension" : "973", "isMain": true], "BD" : ["phoneExtension" : "880", "isMain": true], "BB" : ["phoneExtension" : "1", "isMain": false], "BY" : ["phoneExtension" : "375", "isMain" : true], "BE" : ["phoneExtension": "32", "isMain": true], "BZ" : ["phoneExtension": "501", "isMain": true], "BJ" : ["phoneExtension" : "229", "isMain" : true], "BM" : ["phoneExtension" : "1", "isMain": false], "BT" : ["phoneExtension": "975", "isMain": true], "BO" : ["phoneExtension" : "591", "isMain": true], "BA" : ["phoneExtension" : "387", "isMain" : true], "BW" : ["phoneExtension" : "267", "isMain": true], "BR" : ["phoneExtension": "55", "isMain": true], "IO" : ["phoneExtension": "246", "isMain": true], "VG" : ["phoneExtension": "1", "isMain": false], "BN" : ["phoneExtension": "673", "isMain": true], "BG" : ["phoneExtension": "359", "isMain": true], "BF" :["phoneExtension": "226", "isMain": true], "BI" : ["phoneExtension": "257", "isMain": true], "KH" : ["phoneExtension": "855", "isMain": true], "CM" : ["phoneExtension": "237", "isMain": true], "CA" : ["phoneExtension": "1", "isMain": false], "CV" : ["phoneExtension" : "238", "isMain" : true], "KY" : ["phoneExtension" : "1", "isMain": false], "CF" : ["phoneExtension": "236", "isMain": true], "TD" : ["phoneExtension": "235", "isMain": true], "CL" : ["phoneExtension": "56", "isMain": true], "CN" : ["phoneExtension" : "86", "isMain": true], "CX" : ["phoneExtension" : "61", "isMain" : false], "CC" : ["phoneExtension" : "61", "isMain": false], "CO" : ["phoneExtension" : "57", "isMain": true], "KM" : ["phoneExtension": "269", "isMain": true], "CK" : ["phoneExtension": "682", "isMain": true], "CR" : ["phoneExtension" : "506", "isMain": true], "HR" : ["phoneExtension": "385", "isMain" : true], "CU" : ["phoneExtension": "53", "isMain": true], "CW" : ["phoneExtension": "599", "isMain": true], "CY" : ["phoneExtension" : "357", "isMain": true], "CZ" : ["phoneExtension": "420", "isMain": true], "CD" :["phoneExtension": "243", "isMain": true], "DK" : ["phoneExtension": "45", "isMain": true], "DJ" : ["phoneExtension" : "253", "isMain": true], "DM" : ["phoneExtension": "1", "isMain": false], "DO" : ["phoneExtension" : "1", "isMain": false], "TL" : ["phoneExtension": "670", "isMain": true], "EC" : ["phoneExtension" : "593", "isMain": true], "EG" : ["phoneExtension": "20", "isMain": true], "SV" : ["phoneExtension" : "503", "isMain" : true], "GQ" : ["phoneExtension" : "240", "isMain": true], "ER" : ["phoneExtension" : "291", "isMain": true], "EE" : ["phoneExtension" : "372", "isMain": true], "ET" : ["phoneExtension" : "251", "isMain": true], "FK" : ["phoneExtension" : "500", "isMain": true], "FO" : ["phoneExtension": "298", "isMain": true], "FJ" : ["phoneExtension": "679", "isMain": true], "FI" : ["phoneExtension" : "358", "isMain": true], "FR" : ["phoneExtension" : "33", "isMain" : true], "PF" : ["phoneExtension" : "689", "isMain": true], "GA" : ["phoneExtension" : "241", "isMain": true], "GM" : ["phoneExtension" : "220", "isMain" : true], "GE" : ["phoneExtension": "995", "isMain": true], "DE" : ["phoneExtension" : "49", "isMain": true], "GH" : ["phoneExtension" : "233", "isMain": true], "GI" :["phoneExtension" : "350", "isMain": true], "GR" : ["phoneExtension": "30", "isMain": true], "GL" : ["phoneExtension": "299", "isMain": true], "GD" : ["phoneExtension": "1", "isMain": false], "GU" : ["phoneExtension": "1", "isMain": false], "GT" : ["phoneExtension": "502", "isMain": true], "GG" : ["phoneExtension": "44", "isMain": false], "GN" : ["phoneExtension": "224", "isMain": true], "GW" : ["phoneExtension" : "245", "isMain": true], "GY" : ["phoneExtension": "592", "isMain": true], "HT" : ["phoneExtension": "509", "isMain": true], "HN" : ["phoneExtension": "504", "isMain": true], "HK" : ["phoneExtension": "652", "isMain": true], "HU" : ["phoneExtension": "36", "isMain": true], "IS" :["phoneExtension": "354", "isMain": true], "IN" : ["phoneExtension": "91", "isMain": true], "ID" :["phoneExtension": "62", "isMain": true], "IR" : ["phoneExtension": "98", "isMain": true], "IQ" : ["phoneExtension" : "964", "isMain" : true], "IE" : ["phoneExtension": "353", "isMain": true], "IM" : ["phoneExtension": "44", "isMain": false], "IL" : ["phoneExtension": "972", "isMain": true], "IT" : ["phoneExtension": "39", "isMain": true], "CI" : ["phoneExtension": "225", "isMain": true], "JM" : ["phoneExtension": "1", "isMain": false], "JP" : ["phoneExtension": "81", "isMain": true], "JE" : ["phoneExtension": "44", "isMain": false], "JO" : ["phoneExtension" : "962", "isMain": true], "KZ" : ["phoneExtension" : "7", "isMain": false], "KE" : ["phoneExtension" : "254", "isMain": true], "KI" : ["phoneExtension" : "686", "isMain": true], "XK" : ["phoneExtension": "383", "isMain": true], "KW" : ["phoneExtension": "965", "isMain": true], "KG" : ["phoneExtension": "996", "isMain": true], "LA" : ["phoneExtension": "856", "isMain": true], "LV" : ["phoneExtension": "371", "isMain": true], "LB" : ["phoneExtension": "961", "isMain": true], "LS" : ["phoneExtension": "266", "isMain": true], "LR" : ["phoneExtension": "231", "isMain": true], "LY" : ["phoneExtension": "218", "isMain": true], "LI" : ["phoneExtension": "423", "isMain": true], "LT" : ["phoneExtension": "370", "isMain": true], "LU" : ["phoneExtension": "352", "isMain": true], "MO" : ["phoneExtension": "853", "isMain": true], "MK" : ["phoneExtension": "389", "isMain": true], "MG" : ["phoneExtension": "261", "isMain": true], "MW" : ["phoneExtension": "265", "isMain": true], "MY" : ["phoneExtension": "60", "isMain": true], "MV" : ["phoneExtension": "960", "isMain": true], "ML" : ["phoneExtension": "223", "isMain": true], "MT" : ["phoneExtension": "356", "isMain": true], "MH" : ["phoneExtension": "692", "isMain": true], "MR" : ["phoneExtension": "222", "isMain": true], "MU" : ["phoneExtension": "230", "isMain": true], "YT" : ["phoneExtension": "262", "isMain": true], "MX" : ["phoneExtension": "52", "isMain": true], "FM" : ["phoneExtension": "691", "isMain": true], "MD" : ["phoneExtension": "373", "isMain": true], "MC" : ["phoneExtension": "377", "isMain": true], "MN" : ["phoneExtension": "976", "isMain": true], "ME" : ["phoneExtension": "382", "isMain": true], "MS" : ["phoneExtension": "1", "isMain": false], "MA" : ["phoneExtension": "212", "isMain": true], "MZ" : ["phoneExtension": "258", "isMain": true], "MM" : ["phoneExtension": "95", "isMain": true], "NA": ["phoneExtension": "264", "isMain": true], "NR" : ["phoneExtension": "674", "isMain": true], "NP" : ["phoneExtension": "977", "isMain": true], "NL" : ["phoneExtension": "31", "isMain": true], "AN" : ["phoneExtension": "599", "isMain": true], "NC" : ["phoneExtension": "687", "isMain": true], "NZ" : ["phoneExtension": "64", "isMain": true], "NI" : ["phoneExtension": "505", "isMain": true], "NE" : ["phoneExtension": "227", "isMain": true], "NG" : ["phoneExtension": "234", "isMain": true], "NU" : ["phoneExtension": "683", "isMain": true], "KP" : ["phoneExtension": "850", "isMain": true], "MP" : ["phoneExtension": "1", "isMain": false], "NO" : ["phoneExtension": "47", "isMain": true], "OM" : ["phoneExtension": "968", "isMain": true], "PK" : ["phoneExtension": "92", "isMain": true], "PW" : ["phoneExtension": "680", "isMain": true], "PS" : ["phoneExtension": "970", "isMain": true], "PA" : ["phoneExtension": "507", "isMain": true], "PG" : ["phoneExtension": "675", "isMain": true], "PY" : ["phoneExtension": "595", "isMain": true], "PE" : ["phoneExtension": "51", "isMain": true], "PH" : ["phoneExtension": "63", "isMain": true], "PN" :["phoneExtension": "64", "isMain": false], "PL" : ["phoneExtension": "48", "isMain": true], "PT" : ["phoneExtension": "351", "isMain": true], "PR" : ["phoneExtension": "1", "isMain": false], "QA" : ["phoneExtension": "974", "isMain": true], "CG" : ["phoneExtension": "242", "isMain": true], "RE" : ["phoneExtension": "262", "isMain": false], "RO" : ["phoneExtension": "40", "isMain": true], "RU" : ["phoneExtension": "7", "isMain": true], "RW" : ["phoneExtension": "250", "isMain": true], "BL" : ["phoneExtension": "590", "isMain": true], "SH": ["phoneExtension": "290", "isMain": true], "KN" : ["phoneExtension": "1", "isMain": false], "LC" : ["phoneExtension": "1", "isMain": false], "MF" : ["phoneExtension": "590", "isMain": false], "PM" : ["phoneExtension": "508", "isMain": true], "VC": ["phoneExtension": "1", "isMain": false], "WS" : ["phoneExtension": "685", "isMain": true], "SM" : ["phoneExtension": "378", "isMain": true], "ST" : ["phoneExtension": "239", "isMain": true], "SA" : ["phoneExtension": "966", "isMain": true], "SN" : ["phoneExtension": "221", "isMain": true], "RS" : ["phoneExtension": "381", "isMain": true], "SC" : ["phoneExtension": "248", "isMain": true], "SL" : ["phoneExtension": "232", "isMain": true], "SG" : ["phoneExtension": "65", "isMain": true], "SX" : ["phoneExtension": "1", "isMain": false], "SK" : ["phoneExtension": "421", "isMain": true], "SI" : ["phoneExtension": "386", "isMain": true], "SB" : ["phoneExtension": "677", "isMain": true], "SO" : ["phoneExtension": "252", "isMain": true], "ZA" : ["phoneExtension": "27", "isMain": true], "KR" : ["phoneExtension": "82", "isMain": true], "SS" : ["phoneExtension": "211", "isMain": true], "ES" : ["phoneExtension": "34", "isMain": true], "LK" : ["phoneExtension": "94", "isMain": true], "SD" : ["phoneExtension": "249", "isMain": true], "SR" : ["phoneExtension": "597", "isMain": true], "SJ" : ["phoneExtension": "47", "isMain": true], "SZ" : ["phoneExtension": "268", "isMain": true], "SE" : ["phoneExtension": "46", "isMain": true], "CH" : ["phoneExtension": "41", "isMain": true], "SY" : ["phoneExtension": "963", "isMain": true], "TW" : ["phoneExtension": "886", "isMain": true], "TJ" : ["phoneExtension": "992", "isMain": true], "TZ" : ["phoneExtension": "255", "isMain": true], "TH" : ["phoneExtension": "66", "isMain": true], "TG": ["phoneExtension": "228", "isMain": true], "TK" : ["phoneExtension": "690", "isMain": true], "TO" : ["phoneExtension": "676", "isMain": true], "TT" :["phoneExtension": "1", "isMain": false], "TN" : ["phoneExtension": "216", "isMain": true], "TR" : ["phoneExtension": "90", "isMain": true], "TM" : ["phoneExtension": "993", "isMain": true], "TC" : ["phoneExtension": "1", "isMain": false], "TV" : ["phoneExtension": "688", "isMain": true], "VI" : ["phoneExtension": "1", "isMain": false], "UG" : ["phoneExtension": "256", "isMain": true], "UA" : ["phoneExtension": "380", "isMain": true], "AE": ["phoneExtension": "971", "isMain": true], "GB" : ["phoneExtension": "44", "isMain": true], "US" : ["phoneExtension": "1", "isMain": true], "UY" : ["phoneExtension": "598", "isMain": true], "UZ" : ["phoneExtension": "998", "isMain": true], "VU" : ["phoneExtension": "678", "isMain": true], "VA" : ["phoneExtension": "379", "isMain": true], "VE" : ["phoneExtension": "58", "isMain": true], "VN" : ["phoneExtension": "84", "isMain": true], "WF" : ["phoneExtension": "681", "isMain": true], "EH" : ["phoneExtension": "212", "isMain": true], "YE" : ["phoneExtension": "967", "isMain": true], "ZM" : ["phoneExtension": "260", "isMain": true], "ZW" : ["phoneExtension": "263", "isMain": true]]
}
public class Country {
public var name: String
public var phoneExtension: String?
public var countryCode: String
public var isMain: Bool?
public init(name: String, phoneExtension: String?, countryCode: String, isMain: Bool?) {
self.name = name
self.phoneExtension = phoneExtension
self.countryCode = countryCode
self.isMain = isMain
}
}
Here's a complete list. Others had missing codes
static let countryPrefixes: [String: String] = ["AF": "93",
"AL": "355",
"DZ": "213",
"AS": "1",
"AD": "376",
"AO": "244",
"AI": "1", "AQ": "672",
"AG": "1",
"AR": "54",
"AM": "374",
"AW": "297",
"AU": "61",
"AT": "43",
"AZ": "994",
"BS": "1",
"BH": "973",
"BD": "880",
"BB": "1",
"BY": "375",
"BE": "32",
"BZ": "501",
"BJ": "229",
"BM": "1",
"BT": "975",
"BA": "387",
"BW": "267",
"BR": "55",
"IO": "246",
"BG": "359",
"BF": "226",
"BI": "257",
"KH": "855",
"CM": "237",
"CA": "1",
"CV": "238",
"KY": "345",
"CF": "236",
"TD": "235",
"CL": "56",
"CN": "86",
"CX": "61",
"CO": "57",
"KM": "269",
"CG": "242",
"CK": "682",
"CR": "506",
"HR": "385",
"CU": "53",
"CY": "537",
"CZ": "420",
"DK": "45",
"DJ": "253",
"DM": "1",
"DO": "1",
"EC": "593",
"EG": "20",
"SV": "503",
"GQ": "240",
"ER": "291",
"EE": "372",
"ET": "251",
"FO": "298",
"FJ": "679",
"FI": "358",
"FR": "33",
"GF": "594",
"PF": "689",
"GA": "241",
"GM": "220",
"GE": "995",
"DE": "49",
"GH": "233",
"GI": "350",
"GR": "30",
"GL": "299",
"GD": "1",
"GP": "590",
"GU": "1",
"GT": "502",
"GN": "224",
"GW": "245",
"GY": "595",
"HT": "509",
"HN": "504",
"HU": "36",
"IS": "354",
"IN": "91",
"ID": "62",
"IQ": "964",
"IE": "353",
"IL": "972",
"IT": "39",
"JM": "1",
"JP": "81",
"JO": "962",
"KZ": "77",
"KE": "254",
"KI": "686",
"KW": "965",
"KG": "996",
"LV": "371",
"LB": "961",
"LS": "266",
"LR": "231",
"LI": "423",
"LT": "370",
"LU": "352",
"MG": "261",
"MW": "265",
"MY": "60",
"MV": "960",
"ML": "223",
"MT": "356",
"MH": "692",
"MQ": "596",
"MR": "222",
"MU": "230",
"YT": "262",
"MX": "52",
"MC": "377",
"MN": "976",
"ME": "382",
"MS": "1",
"MA": "212",
"MM": "95",
"NA": "264",
"NR": "674",
"NP": "977",
"NL": "31",
"AN": "599",
"NC": "687",
"NZ": "64",
"NI": "505",
"NE": "227",
"NG": "234",
"NU": "683",
"NF": "672",
"MP": "1",
"NO": "47",
"OM": "968",
"PK": "92",
"PW": "680",
"PA": "507",
"PG": "675",
"PY": "595",
"PE": "51",
"PH": "63",
"PL": "48",
"PT": "351",
"PR": "1",
"QA": "974",
"RO": "40",
"RW": "250",
"WS": "685",
"SM": "378",
"SA": "966",
"SN": "221",
"RS": "381",
"SC": "248",
"SL": "232",
"SG": "65",
"SK": "421",
"SI": "386",
"SB": "677",
"ZA": "27",
"GS": "500",
"ES": "34",
"LK": "94",
"SD": "249",
"SR": "597",
"SZ": "268",
"SE": "46",
"CH": "41",
"TJ": "992",
"TH": "66",
"TG": "228",
"TK": "690",
"TO": "676",
"TT": "1",
"TN": "216",
"TR": "90",
"TM": "993",
"TC": "1",
"TV": "688",
"UG": "256",
"UA": "380",
"AE": "971",
"GB": "44",
"US": "1",
"UY": "598",
"UZ": "998",
"VU": "678",
"WF": "681",
"YE": "967",
"ZM": "260",
"ZW": "263",
"BO": "591",
"BN": "673",
"CC": "61",
"CD": "243",
"CI": "225",
"FK": "500",
"GG": "44",
"VA": "379",
"HK": "852",
"IR": "98",
"IM": "44",
"JE": "44",
"KP": "850",
"KR": "82",
"LA": "856",
"LY": "218",
"MO": "853",
"MK": "389",
"FM": "691",
"MD": "373",
"MZ": "258",
"PS": "970",
"PN": "872",
"RE": "262",
"RU": "7",
"BL": "590",
"SH": "290",
"KN": "1",
"LC": "1",
"MF": "590",
"PM": "508",
"VC": "1",
"ST": "239",
"SO": "252",
"SJ": "47",
"SY": "963",
"TW": "886",
"TZ": "255",
"TL": "670",
"VE": "58",
"VN": "84",
"VG": "284",
"VI": "340", "EH": "121"]
As far as I am aware, there is no built in method for getting this information. However, you could store the data in your application and look it up based on the country code you just obtained.
A full list of known codes is on Wikipedia
You could store them as a long .plist file, which you can then load in and query as a dictionary keyed by the country code.
let phoneUtil = NBPhoneNumberUtil()
if let countryCode = (Locale.current as NSLocale).object(forKey: .countryCode) as? String {
}
let device = Locale.current.regionCode
do {
let phoneNumber: NBPhoneNumber = try phoneUtil.parse(withPhoneCarrierRegion:phone_txt.text)
let code:String = try phoneUtil.format(phoneNumber, numberFormat: .E164)
let national:String = try phoneUtil.format(phoneNumber, numberFormat: .NATIONAL)
let international:String = try phoneUtil.format(phoneNumber, numberFormat: .INTERNATIONAL)
countryname_lbl.text = phoneUtil.getRegionCode(forCountryCode:phoneNumber.countryCode)!
let numberrr = phoneUtil.getNationalSignificantNumber(phoneNumber)
print("number::",numberrr)
let valid = phoneUtil.isValidNumber(phoneNumber)
print("valid:",valid)
code_lbl.text = code
number_lbl.text = international
national_lbl.text = national
}
catch let error as NSError {
print(error.localizedDescription)
}
}
Download file country_dial_info and add to project
https://gist.github.com/xxcombat/b1cef4a501c7ae358720cd192da3ed48
Download file and add to project
https://gist.github.com/xxcombat/fe08f22b5ecbb629b6900aba9abfd0aa
Example
let regionCode = Locale.current.regionCode
print(regionCode) // "UA"
let phoneCodes: [DialCodeInfo]
let dialCodes = DialCodes()
phoneCodes = dialCodes.databaseCodes ?? []
let myPhoneCode = databaseCodes?.first(where: { info in
info.code == regionCode
})
print(myPhoneCode)
// DialCodeInfo(name: "Ukraine", flag: "🇺🇦", code: "UA", dialcode: "+380"))
I'm getting a method or variable not defined when trying to use an array defined in a function in a module.
Here are the files:
/lib/states.rb
module States
def fifty_states
[
'AL',
'AK',
'AZ',
'AR',
'CA',
'CO',
'CT',
'DE',
'FL',
'GA',
'HI',
'ID',
'IL',
'IN',
'IA',
'KS',
'KY',
'LA',
'ME',
'MD',
'MA',
'MI',
'MN',
'MS',
'MO',
'MT',
'NE',
'NV',
'NH',
'NJ',
'NM',
'NY',
'NC',
'ND',
'OH',
'OK',
'OR',
'PA',
'RI',
'SC',
'SD',
'TN',
'TX',
'UT',
'VT',
'VA',
'WA',
'WV',
'WI',
'WY'
]
end
end
/app/controller/player_to_team_histories_controller.rb
class PlayerToTeamHistory < ActiveRecord::Base
include States
def self.distinct_states
joins(:player).select("DISTINCT players.HometownState").where("players.HometownState IN (?)", fifty_states)
end
If I open a console I can do this just fine:
>> include States
Object
>> fifty_states
["AL", "AK", "AZ", "AR", "CA", "CO", "CT", "DE", "FL", "GA", "HI", "ID", "IL", "IN", "IA", "KS", "KY", "LA", "ME", "MD", "MA", "MI", "MN", "MS", "MO", "MT", "NE", "NV", "NH", "NJ", "NM", "NY", "NC", "ND", "OH", "OK", "OR", "PA", "RI", "SC", "SD", "TN", "TX", "UT", "VT", "VA", "WA", "WV", "WI", "WY"]
I think you're confusing class with instance here. If you want to call fifty_states from inside a class method (i.e. self.distinct_states), then you'll have to use extend, not include:
module A
def foo
"myfoo"
end
end
class B
extend A
def self.bar
foo
end
end
B.bar
#=> "myfoo"
Note however that you then cannot call the method from an instance:
b = B.new
b.bar
#=> NoMethodError: undefined method `bar' for #<B:0x007fefc4e19db0>
Here's an article with more discussion on include vs extend.
The message at the end sums things up well:
Use include for instance methods and extend for class methods. Also, it is sometimes ok to use include to add both instance and class methods. Both are really handy and allow for a great amount of code reuse. They also allow you to avoid deep inheritance, and instead just modularize code and include it where needed, which is much more the ruby way.