0

Using Swift i would like to sort the below array using the country name [0][1] instead of country code. Not sure how to achieve this.

let prefixCodes = [["AD", "Andorra"], ["AE", "United Arab Emirates"], ["AF", "Afghanistan"], ["AG", "Antigua & Barbuda"], ["AI", "Anguilla"], ["AL", "Albania"], ["AM", "Armenia"], ["AO", "Angola"], ["AQ", "Antarctica"], ["AR", "Argentina"], ["AS", "American Samoa"], ["AT", "Austria"], ["AU", "Australia"], ["AW", "Aruba"], ["AX", "Åland Islands"], ["AZ", "Azerbaijan"], ["BA", "Bosnia & Herzegovina"], ["BB", "Barbados"], ["BD", "Bangladesh"], ["BE", "Belgium"], ["BF", "Burkina Faso"], ["BG", "Bulgaria"], ["BH", "Bahrain"], ["BI", "Burundi"], ["BJ", "Benin"], ["BL", "St. Barthélemy"], ["BM", "Bermuda"], ["BN", "Brunei"], ["BO", "Bolivia"], ["BQ", "Caribbean Netherlands"], ["BR", "Brazil"], ["BS", "Bahamas"], ["BT", "Bhutan"], ["BV", "Bouvet Island"], ["BW", "Botswana"], ["BY", "Belarus"], ["BZ", "Belize"], ["CA", "Canada"], ["CC", "Cocos (Keeling) Islands"], ["CD", "Congo - Kinshasa"], ["CF", "Central African Republic"], ["CG", "Congo - Brazzaville"], ["CH", "Switzerland"], ["CI", "Côte d’Ivoire"], ["CK", "Cook Islands"], ["CL", "Chile"], ["CM", "Cameroon"], ["CN", "China"], ["CO", "Colombia"], ["CR", "Costa Rica"], ["CU", "Cuba"], ["CV", "Cape Verde"], ["CW", "Curaçao"], ["CX", "Christmas Island"], ["CY", "Cyprus"], ["CZ", "Czech Republic"], ["DE", "Germany"], ["DJ", "Djibouti"], ["DK", "Denmark"], ["DM", "Dominica"], ["DO", "Dominican Republic"], ["DZ", "Algeria"], ["EC", "Ecuador"], ["EE", "Estonia"], ["EG", "Egypt"], ["EH", "Western Sahara"], ["ER", "Eritrea"], ["ES", "Spain"], ["ET", "Ethiopia"], ["FI", "Finland"], ["FJ", "Fiji"], ["FK", "Falkland Islands"], ["FM", "Micronesia"], ["FO", "Faroe Islands"], ["FR", "France"], ["GA", "Gabon"], ["GB", "United Kingdom"], ["GD", "Grenada"], ["GE", "Georgia"], ["GF", "French Guiana"], ["GG", "Guernsey"], ["GH", "Ghana"], ["GI", "Gibraltar"], ["GL", "Greenland"], ["GM", "Gambia"], ["GN", "Guinea"], ["GP", "Guadeloupe"], ["GQ", "Equatorial Guinea"], ["GR", "Greece"], ["GS", "So. Georgia & So. Sandwich Isl."], ["GT", "Guatemala"], ["GU", "Guam"], ["GW", "Guinea-Bissau"], ["GY", "Guyana"], ["HK", "Hong Kong SAR China"], ["HM", "Heard & McDonald Islands"], ["HN", "Honduras"], ["HR", "Croatia"], ["HT", "Haiti"], ["HU", "Hungary"], ["ID", "Indonesia"], ["IE", "Ireland"], ["IL", "Israel"], ["IM", "Isle of Man"], ["IN", "India"], ["IO", "British Indian Ocean Territory"], ["IQ", "Iraq"], ["IR", "Iran"], ["IS", "Iceland"], ["IT", "Italy"], ["JE", "Jersey"], ["JM", "Jamaica"], ["JO", "Jordan"], ["JP", "Japan"], ["KE", "Kenya"], ["KG", "Kyrgyzstan"], ["KH", "Cambodia"], ["KI", "Kiribati"], ["KM", "Comoros"], ["KN", "St. Kitts & Nevis"], ["KP", "North Korea"], ["KR", "South Korea"], ["KW", "Kuwait"], ["KY", "Cayman Islands"], ["KZ", "Kazakhstan"], ["LA", "Laos"], ["LB", "Lebanon"], ["LC", "St. Lucia"], ["LI", "Liechtenstein"], ["LK", "Sri Lanka"], ["LR", "Liberia"], ["LS", "Lesotho"], ["LT", "Lithuania"], ["LU", "Luxembourg"], ["LV", "Latvia"], ["LY", "Libya"], ["MA", "Morocco"], ["MC", "Monaco"], ["MD", "Moldova"], ["ME", "Montenegro"], ["MF", "St. Martin"], ["MG", "Madagascar"], ["MH", "Marshall Islands"], ["MK", "Macedonia"], ["ML", "Mali"], ["MM", "Myanmar (Burma)"], ["MN", "Mongolia"], ["MO", "Macau SAR China"], ["MP", "Northern Mariana Islands"], ["MQ", "Martinique"], ["MR", "Mauritania"], ["MS", "Montserrat"], ["MT", "Malta"], ["MU", "Mauritius"], ["MV", "Maldives"], ["MW", "Malawi"], ["MX", "Mexico"], ["MY", "Malaysia"], ["MZ", "Mozambique"], ["NA", "Namibia"], ["NC", "New Caledonia"], ["NE", "Niger"], ["NF", "Norfolk Island"], ["NG", "Nigeria"], ["NI", "Nicaragua"], ["NL", "Netherlands"], ["NO", "Norway"], ["NP", "Nepal"], ["NR", "Nauru"], ["NU", "Niue"], ["NZ", "New Zealand"], ["OM", "Oman"], ["PA", "Panama"], ["PE", "Peru"], ["PF", "French Polynesia"], ["PG", "Papua New Guinea"], ["PH", "Philippines"], ["PK", "Pakistan"], ["PL", "Poland"], ["PM", "St. Pierre & Miquelon"], ["PN", "Pitcairn Islands"], ["PR", "Puerto Rico"], ["PS", "Palestinian Territories"], ["PT", "Portugal"], ["PW", "Palau"], ["PY", "Paraguay"], ["QA", "Qatar"], ["RE", "Réunion"], ["RO", "Romania"], ["RS", "Serbia"], ["RU", "Russia"], ["RW", "Rwanda"], ["SA", "Saudi Arabia"], ["SB", "Solomon Islands"], ["SC", "Seychelles"], ["SD", "Sudan"], ["SE", "Sweden"], ["SG", "Singapore"], ["SH", "St. Helena"], ["SI", "Slovenia"], ["SJ", "Svalbard & Jan Mayen"], ["SK", "Slovakia"], ["SL", "Sierra Leone"], ["SM", "San Marino"], ["SN", "Senegal"], ["SO", "Somalia"], ["SR", "Suriname"], ["SS", "South Sudan"], ["ST", "São Tomé & Príncipe"], ["SV", "El Salvador"], ["SX", "Sint Maarten"], ["SY", "Syria"], ["SZ", "Swaziland"], ["TC", "Turks & Caicos Islands"], ["TD", "Chad"], ["TF", "French Southern Territories"], ["TG", "Togo"], ["TH", "Thailand"], ["TJ", "Tajikistan"], ["TK", "Tokelau"], ["TL", "Timor-Leste"], ["TM", "Turkmenistan"], ["TN", "Tunisia"], ["TO", "Tonga"], ["TR", "Turkey"], ["TT", "Trinidad & Tobago"], ["TV", "Tuvalu"], ["TW", "Taiwan"], ["TZ", "Tanzania"], ["UA", "Ukraine"], ["UG", "Uganda"], ["UM", "U.S. Outlying Islands"], ["US", "United States"], ["UY", "Uruguay"], ["UZ", "Uzbekistan"], ["VA", "Vatican City"], ["VC", "St. Vincent & Grenadines"], ["VE", "Venezuela"], ["VG", "British Virgin Islands"], ["VI", "U.S. Virgin Islands"], ["VN", "Vietnam"], ["VU", "Vanuatu"], ["WF", "Wallis & Futuna"], ["WS", "Samoa"], ["YE", "Yemen"], ["YT", "Mayotte"], ["ZA", "South Africa"], ["ZM", "Zambia"], ["ZW", "Zimbabwe"]]

Thank you in advance.

3
  • Have you tried any code using Swift's inbuilt array sort function? Commented Mar 18, 2016 at 8:27
  • not sure how to use this one. prefixCodes.sort { (<#[String]#>, <#[String]#>) -> Bool in <#code#> } Commented Mar 18, 2016 at 8:32
  • See the description of the sort closure here - developer.apple.com/library/ios/documentation/Swift/Conceptual/… Commented Mar 18, 2016 at 8:41

4 Answers 4

1

With sort and the shorthand arguments you can order the second element in your 2D array like this:

let sortedAfterCountryNames = prefixCodes.sort{ $0[1] < $1[1] }

print(sortedAfterCountryNames)
// [["AF", "Afghanistan"], ["AL", "Albania"], ["DZ", "Algeria"], ["AS", "American Samoa"], ...
Sign up to request clarification or add additional context in comments.

2 Comments

Thank you very much. Thats exactly what i was looking for.
Nice, that I could help you. I added some further informations and a link for more details about closures, the sort method and the short hand arguments
1

Hope this will help you.

let sortedArray = prefixCodes.sort { (first, second) -> Bool in
  return first.last < second.last
}

Comments

1

You should use the sort method to sort your array.

Let's first create an unsorted array:

var arr = [["A", "Hello world"], 
    ["C", "Bye world"], 
    ["B", "idk what to say here"]]

Now let's look at what arguments the sort method needs. Apparently it needs a closure of the following signature:

([String], [String]) -> Bool

The most straightforward (but not so swifty) approach would be to write a function with that signature:

func myFunction (first: [String], second: [String]) -> Bool {

}

In that function, you need to decide whether the algorithm should swap the two arguments. If it should not, return true, otherwise false. I think if you want to sort in alphabetical order, you should just compare the two strings

return first[1] < second[1]

You access the element at index 1 because that is where you store the country names, right?

Then, call sort with the function

arr = arr.sort(myFunction)

However, that is not very swifty. To make this the most swifty, you can do this:

arr.sort {
    $0[1] < $1[1]
}

Much better!

Comments

0

You may do the following:

prefixCodes.sort { $0[1] < $1[1] }

But to be safer, I think that you should define a Country struct like this:

struct Country {
    let code: String
    let name: String

    init(_ code: String, _ name: String) {
        self.code = code
        self.name = name
    }
}

let countries = [Country("AD", "Andorra"), Country("AE", "United Arab Emirates"), Country("BQ", "Caribbean Netherlands")]

print(countries.sort { $0.name < $1.name })

So that if you want to add more details to your countries, you will not have a chance to break your sort closure.


Or if you want to keep things simple but still enforce strong typing, you could use tuples:

let countries = [("AD", "Andorra"), ("AE", "United Arab Emirates"), ("BQ", "Caribbean Netherlands")]

print(countries.sort { $0.1 < $1.1 })

If you mix different tuple lengths in your array:

let countries = [("AD", "Andorra"), ("toto"), ("tata", "titi", "tutu")]

Swift will return this error:

error: type of expression is ambiguous without more context

1 Comment

I added a tuple solution which lets Swift ensure that all members of your array have the same size, without having to declare a struct or using a constructor. If my answer was helpful, you may want to upvote it, thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.