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
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.
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