首页 > 解决方案 > 对 UnitMass 类型的数组进行排序

问题描述

所以我想对一个 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())
}

标签: arraysswiftsorting

解决方案


我建议建立一个字典,将 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. 调用创建一个元组列表.enumerated()specificLayoutOfUnits其中第一个元素是位置,第二个是单位:[(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没有位置的值被排序到数组的末尾。

推荐阅读