【问题标题】:Sort an array of type UnitMass对 UnitMass 类型的数组进行排序
【发布时间】:2020-03-31 11:44:51
【问题描述】:

所以我想对 UnitMass 数组进行排序,但我想在特定布局中对其进行排序。我知道如何按字母顺序对其进行排序,但这并不是我想要知道如何做到这一点的任何人?

是否可以像这样对数组进行排序,我该怎么做?或者我可以定义数组的外观吗?

let spesificLayoutOfUnits =[ UnitMass.grams, UnitMass.kilograms, UnitMass.metricTons, UnitMass.stones, UnitMass.pounds, UnitMass.ounces ]
var toBeSorted = [ UnitMass.kilograms, UnitMass.pounds, UnitMass.metricTons, UnitMass.ounces, UnitMass.grams ]

我使用 spesificLayoutOfUnits 数组作为用户拥有的所有选项的数组。然后将此数组中的单位添加到 toBeSorted 数组中,该数组是所选单位的数组。

var options = spesificLayoutOfUnits as! [UnitMass]
var tempArray = [UnitMass]()
while toBeSorted.endIndex > positionOfUnit {
   tempArray.append(toBeSorted.removeLast())
}
toBeSorted.append(options.remove(at: positionOfUnit))
while !tempArray.isEmpty {
    toBeSorted.append(tempArray.removeLast())
}

【问题讨论】:

  • 如果数组是硬编码的,那么只需按顺序添加值开始,如果不是硬编码,请多解释一下你想要做什么。
  • 我想要排序的数组总是这样开始:[ UnitMass.kilograms, UnitMass.stones, UnitMass.pounds, UnitMass.ounces ],但是当轻按开关时,它将删除单位或添加它,我正在努力将单位放在正确的位置,例如(toBeSorted[0] 删除,然后添加一个新单位。)只要没有删除任何内容,一切都很好。我已经添加了要添加的代码。 @JoakimDanielson
  • 我想说,如果这些是数组中唯一可能的居民,请不要添加或删除任何东西。只需切换每个元素是否有效。仍然不清楚真正的目标是什么,但这是我最初的想法。换句话说,保留两个列表,一个是您拥有的,另一个是说明要过滤掉的列表。
  • 我的做法是使用 toBeSorted 数组,然后创建一个包含文本字段和标签的堆栈视图。但是如果用户按住一个按钮,它将创建一个包含开关和标签的 spesificLayoutOfUnits 数组的堆栈视图。 @马特

标签: arrays swift sorting


【解决方案1】:

我建议建立一个字典,将 UnitMass 映射到所需位置,然后使用它进行排序:

let specificLayoutOfUnits = [ UnitMass.grams, UnitMass.kilograms, UnitMass.metricTons, UnitMass.stones, UnitMass.pounds, UnitMass.ounces ]

// Create a dictionary to map UnitMass to Int position   
var position = [UnitMass : Int]()

for (idx, um) in specificLayoutOfUnits.enumerated() {
    position[um] = idx
}

var toBeSorted = [ UnitMass.kilograms, UnitMass.pounds, UnitMass.metricTons, UnitMass.ounces, UnitMass.grams ]

// Sort the array by position.  Use Int.max if the UnitMass has no
// position to sort it to the end of the array
let sorted = toBeSorted.sorted { position[$0, default: Int.max] < position[$1, default: Int.max] }

说明:

  1. specificLayoutOfUnits 上调用.enumerated() 会创建一个元组列表,其中第一个元素是位置,第二个元素是单位:[(0, UnitMass.grams), (1, UnitMass.kilograms), (2, UnitMass.metricTons), ...]
  2. 接下来,我们遍历这个列表来构建一个字典,将单元映射到它的位置:[UnitMass.grams: 0, UnitMass.kilograms: 1, UnitMass.metricTons: 2, ...]
  3. 此字典用于按第一个数组中的元素位置对第二个数组进行排序。 .sorted(by:) 接受一个比较两个元素的闭包并返回一个Bool,它表示第一个元素是否在第二个元素之前排序。在这里,我们使用第一个数组中两个元素的位置来决定顺序。请注意,第二个数组中可能有一个元素没有出现在第一个数组中。在这种情况下,我们使用字典查找的特殊版本来返回Int.max 的位置。这将导致所有没有位置的 UnitMass 值被排序到数组的末尾。

【讨论】:

  • 谢谢你,效果很好。我很难理解它是如何工作的,你能给我解释一下吗? @vacawama
  • 我添加了一个解释。如果我需要进一步澄清,请告诉我。
  • 谢谢你@vacawama
猜你喜欢
  • 2020-12-05
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 2010-09-17
  • 1970-01-01
  • 1970-01-01
  • 2021-12-15
  • 2021-01-28
相关资源
最近更新 更多