Swift array sort alphabetically and in group order

Swift array sort alphabetically and in group order



i am trying to order an array alphabetically and by group name's



My list is:


Name: A
Group: cats

Name: B
Group: dogs

Name: C
Group: cats



I have done the alphabetical order ordered by Name and it's showing me the following order:


A
cats

B
dogs

C
cats



But i'm having a migraine trying to sort them by the group, ex:


A
cats

C
cats

B
dogs



What i tried so far for alphabetical order and groups order:


case alpha:
results.sorted $0.first_name < $1.first_name
case grouped:
results.sorted $0.group_name == $1.group_name






You need a single sort operation. In the closure, If the names are the same then compare by group otherwise compare by name

– Paulw11
Sep 9 '18 at 21:04







I have a segmented control where i can select the type of the sort, so it does not help me to make it in a single sort operation.

– Bonta Alexandru
Sep 9 '18 at 21:07






So you may need multiple, single sort operations based on the segmented control (and it helps if you put all of your goals in your question), but the way you have it now the first sort is overridden by the second sort. You need to consider both criteria in the one sort operation.

– Paulw11
Sep 9 '18 at 21:09







Your second sort closure isn't even valid as it doesn't perform a relative comparison

– Paulw11
Sep 9 '18 at 21:10







Ok, i edited my question now.

– Bonta Alexandru
Sep 9 '18 at 21:14




2 Answers
2



Try this


struct Animal
let Name: String
let Group: String


let a1 = Animal(Name: "A", Group: "cats")
let a2 = Animal(Name: "B", Group: "dogs")
let a3 = Animal(Name: "C", Group: "cats")

let animals = [a3, a2, a1]

let result = animals.sorted(by: $0.Group < $1.Group).sorted(by: $0.Group == $1.Group && $0.Name < $1.Name )
result //Prints [Name "A", Group "cats", Name "C", Group "cats", Name "B", Group "dogs"]



sorted returns a new array (result) and doesn't sort the initial array (animals) in place.


sorted


result






My code actually does this on another array(a new one), the problem in my case was with a bad string key.. the above code works well

– Bonta Alexandru
Sep 9 '18 at 21:28






Glad I could be of help, have a nice Sunday!

– Carpsen90
Sep 9 '18 at 21:29






Changing your animals to let animals = [a1, a2, a3], I get [SortGroups.Animal(Name: "A", Group: "cats"), SortGroups.Animal(Name: "B", Group: "dogs"), SortGroups.Animal(Name: "C", Group: "cats")], seems your code does not sorting the array correctly.

– OOPer
Sep 9 '18 at 21:35


animals


let animals = [a1, a2, a3]


[SortGroups.Animal(Name: "A", Group: "cats"), SortGroups.Animal(Name: "B", Group: "dogs"), SortGroups.Animal(Name: "C", Group: "cats")]






@OOPer i've updated the answer

– Carpsen90
Sep 9 '18 at 21:39






Still wrong. Try adding let a4 = Animal(Name: "D", Group: "dogs") and let animals = [a1, a2, a3, a4]. Two element lexicographical order cannot be achieved with $0.Group <= $1.Group && $0.Name < $1.Name.

– OOPer
Sep 9 '18 at 21:43


let a4 = Animal(Name: "D", Group: "dogs")


let animals = [a1, a2, a3, a4]


$0.Group <= $1.Group && $0.Name < $1.Name



Try this:


results.sorted ($0.group_name, $0.first_name) < ($1.group_name, $1.first_name)



Example:


struct Item
var first_name: String
var group_name: String


let results = [
Item(first_name: "A", group_name: "cats"),
Item(first_name: "B", group_name: "dogs"),
Item(first_name: "C", group_name: "cats")
]
let sortedResult = results.sorted ($0.group_name, $0.first_name) < ($1.group_name, $1.first_name)
print(sortedResult)
//->[SortGroups.Item(first_name: "A", group_name: "cats"), SortGroups.Item(first_name: "C", group_name: "cats"), SortGroups.Item(first_name: "B", group_name: "dogs")]



An example where Carpsen90's current code fails.


struct Animal
let Name: String
let Group: String


let animals = [
Animal(Name: "B", Group: "rats"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "E", Group: "cats"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "A", Group: "cats"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "E", Group: "cats"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "D", Group: "cats"),
Animal(Name: "A", Group: "cats"),
Animal(Name: "B", Group: "cats"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "D", Group: "rats"),
Animal(Name: "A", Group: "rats"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "D", Group: "dogs"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "A", Group: "rats")
]

let result = animals.sorted(by: $0.Group < $1.Group).sorted(by: $0.Group == $1.Group && $0.Name < $1.Name )
print("[n "+result.map String(describing: $0).joined(separator: ",n ")+"n]")



Output:


[
Animal(Name: "E", Group: "cats"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "A", Group: "cats"),
Animal(Name: "B", Group: "cats"),
Animal(Name: "D", Group: "cats"),
Animal(Name: "E", Group: "cats"),
Animal(Name: "D", Group: "dogs"),
Animal(Name: "A", Group: "cats"),
Animal(Name: "A", Group: "rats"),
Animal(Name: "A", Group: "rats"),
Animal(Name: "B", Group: "rats"),
Animal(Name: "D", Group: "rats")
]



Using tuple comparison for the same input:


let result2 = animals.sorted ($0.Group, $0.Name) < ($1.Group, $1.Name)
print("[n "+result2.map String(describing: $0).joined(separator: ",n ")+"n]")



Output:


[
Animal(Name: "A", Group: "cats"),
Animal(Name: "A", Group: "cats"),
Animal(Name: "B", Group: "cats"),
Animal(Name: "D", Group: "cats"),
Animal(Name: "E", Group: "cats"),
Animal(Name: "E", Group: "cats"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "A", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "B", Group: "dogs"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "C", Group: "dogs"),
Animal(Name: "D", Group: "dogs"),
Animal(Name: "A", Group: "rats"),
Animal(Name: "A", Group: "rats"),
Animal(Name: "B", Group: "rats"),
Animal(Name: "D", Group: "rats")
]






($0.group_name, $0.first_name) < ($1.group_name, $1.first_name) Is this tuple < tuple? Haven't seen that before.

– Fabian
Sep 9 '18 at 21:36


($0.group_name, $0.first_name) < ($1.group_name, $1.first_name)


tuple < tuple






@Fabian, Please check SE-0015 Tuple comparison operators.

– OOPer
Sep 9 '18 at 21:38



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)