我想让用户根据他们的喜好对一系列选项进行排序。我有一个数组保存选项的原始值,一个数组保存来自原始值的更新值。我怎么才能得到剩下的选择呢?我上的是Swift 4.2
我的想法是将两者转换成集合,并使用对称差分。
选项数组提供了最初的选择
排序的数组具有用户级别的值属性(1、2、3或4)
remainingOptions应该包含尚未排序的水果。
然而,我得到了副本。
可以自由地提出其他方法。
struct Option: Hashable {
var title: String
var key: String
var value: Int
}
var apple = Option(title: "Apple", key: "apple", value: 0)
var grape = Option(title: "Grape", key: "grape", value: 0)
var banana = Option(title: "Banana", key: "banana", value: 0)
var papaya = Option(title: "Papaya", key: "papaya", value: 0)
var options = [apple, grape, banana, papaya]
apple.value = 1
grape.value = 2
var ranked = [apple, grape]
let originalSet: Set<Option> = Set(options)
var rankedSet: Set<Option> = Set(ranked)
let remainingOptions = originalSet.symmetricDifference(rankedSet)结果:
{title "Grape", key "grape", value 1}
{title "Apple", key "apple", value 0}
{title "Grape", key "grape", value 2}
{title "Banana", key "banana", value 0}
{title "Apple", key "apple", value 1}
{title "Papaya", key "papaya", value 0}通缉结果:
{title "Banana", key "banana", value 0}
{title "Papaya", key "papaya", value 0}发布于 2019-06-29 10:37:48
问题是,如果两个Option具有相同的title和key,那么它们是相等的,但在默认情况下,Swift也在检查value。因此,两个具有不同Options的value被认为是不同的。
对称差分返回一个新的集合,其中的元素要么在这个集合中,要么在给定的序列中,但这两个元素都没有。因为您已经更改了值,所以您最终得到了两个集合的合并,因为它们没有任何共同点。
您可以通过显式实现hash(into:)函数和==函数来解决这个问题,在检查等式时忽略value:
struct Option: Hashable, CustomStringConvertible {
var title: String
var key: String
var value: Int
var description: String { return "{title: \"\(title)\", key: \"\(key)\", value: \(value)}" }
func hash(into hasher: inout Hasher) {
hasher.combine(title)
hasher.combine(key)
}
static func ==(lhs: Option, rhs: Option) -> Bool {
return lhs.title == rhs.title && lhs.key == rhs.key
}
}
var apple = Option(title: "Apple", key: "apple", value: 0)
var grape = Option(title: "Grape", key: "grape", value: 0)
var banana = Option(title: "Banana", key: "banana", value: 0)
var papaya = Option(title: "Papaya", key: "papaya", value: 0)
var options = [apple, grape, banana, papaya]
apple.value = 1
grape.value = 2
var ranked = [apple, grape]
let originalSet: Set<Option> = Set(options)
var rankedSet: Set<Option> = Set(ranked)
let remainingOptions = originalSet.symmetricDifference(rankedSet)
print(remainingOptions){标题:“番木瓜”,键:“木瓜”,值: 0},{标题:“香蕉”,键:“香蕉”,值: 0}
注意: symmetricDifference接受序列,因此不必将ranked转换为Set,只需使用数组:
let remainingOptions = originalSet.symmetricDifference(ranked)另一个选项:使用Filter
与使用Set和symmetricDifference不同,您可以使用map从ranked数组中获取keys数组,然后在options数组上使用filter获取与这些keys不匹配的remaining选项
let rankedKeys = ranked.map { $0.key }
let remaining = options.filter { !rankedKeys.contains($0.key) }这并不要求您从原始定义中更改Option结构。
https://stackoverflow.com/questions/56816650
复制相似问题