【问题标题】:Swift array sort alphabetically and in group orderSwift数组按字母顺序和组顺序排序
【发布时间】:2018-09-09 20:49:05
【问题描述】:

我正在尝试按字母顺序和组名排序数组

我的清单是:

Name: A
Group: cats

Name: B
Group: dogs

Name: C
Group: cats

我已经按照姓名的字母顺序进行了排序,它向我显示了以下顺序:

A
cats

B
dogs

C
cats

但我有点偏头痛,试图按组对它们进行排序,例如:

A
cats

C
cats

B
dogs

到目前为止我尝试过的字母顺序和组顺序:

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

【问题讨论】:

  • 您需要一个排序操作。在闭包中,如果名称相同,则按组比较,否则按名称比较
  • 我有一个分段控件,我可以在其中选择排序的类型,所以它不能帮助我在单个排序操作中完成它。
  • 因此,您可能需要基于分段控件的多个单一排序操作(如果您将所有目标放在您的问题中,这会有所帮助),但是您拥有的方式现在第一个排序被第二个排序覆盖了。您需要在一次排序操作中考虑这两个条件。
  • 您的第二个排序闭包甚至无效,因为它不执行相对比较
  • 好的,我现在编辑了我的问题。

标签: arrays swift sorting


【解决方案1】:

试试这个:

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

例子:

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")]

Carpsen90 当前代码失败的例子。

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]")

输出:

[
  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")
]

对同一输入使用元组比较:

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

输出:

[
  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) &lt; ($1.group_name, $1.first_name) 这是tuple &lt; tuple 吗?以前没见过。
  • @Fabian,请查看SE-0015 Tuple comparison operators
【解决方案2】:

试试这个

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 返回一个新数组 (result) 并且不对初始数组(动物)进行排序。

【讨论】:

  • 我的代码实际上是在另一个数组(一个新数组)上执行此操作的,在我的情况下,问题是字符串键错误.. 上面的代码运行良好
  • 很高兴能为您提供帮助,祝您周日愉快!
  • 将您的animals 更改为let animals = [a1, a2, a3],我得到[SortGroups.Animal(Name: "A", Group: "cats"), SortGroups.Animal(Name: "B", Group: "dogs"), SortGroups.Animal(Name: "C", Group: "cats")],您的代码似乎没有正确排序数组。
  • 还是错了。尝试添加let a4 = Animal(Name: "D", Group: "dogs")let animals = [a1, a2, a3, a4]$0.Group &lt;= $1.Group &amp;&amp; $0.Name &lt; $1.Name 无法实现两个元素的字典顺序。
  • 我的输出 [SortGroups.Animal(Name: "A", Group: "cats"), SortGroups.Animal(Name: "B", Group: "dogs"), SortGroups. Animal(Name: "C", Group: "cats"), SortGroups.Animal(Name: "D", Group: "dogs")] (Xcode 9.4.1).
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-18
  • 2013-03-18
  • 2017-05-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-25
相关资源
最近更新 更多