首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >集合在可变值中的对称差会造成重复

集合在可变值中的对称差会造成重复
EN

Stack Overflow用户
提问于 2019-06-29 10:04:24
回答 1查看 419关注 0票数 0

我想让用户根据他们的喜好对一系列选项进行排序。我有一个数组保存选项的原始值,一个数组保存来自原始值的更新值。我怎么才能得到剩下的选择呢?我上的是Swift 4.2

我的想法是将两者转换成集合,并使用对称差分。

选项数组提供了最初的选择

排序的数组具有用户级别的值属性(1、2、3或4)

remainingOptions应该包含尚未排序的水果。

然而,我得到了副本。

可以自由地提出其他方法。

代码语言:javascript
复制
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)

结果:

代码语言:javascript
复制
{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}

通缉结果:

代码语言:javascript
复制
{title "Banana", key "banana", value 0}
{title "Papaya", key "papaya", value 0}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-06-29 10:37:48

问题是,如果两个Option具有相同的titlekey,那么它们是相等的,但在默认情况下,Swift也在检查value。因此,两个具有不同Options的value被认为是不同的。

对称差分返回一个新的集合,其中的元素要么在这个集合中,要么在给定的序列中,但这两个元素都没有。因为您已经更改了值,所以您最终得到了两个集合的合并,因为它们没有任何共同点。

您可以通过显式实现hash(into:)函数和==函数来解决这个问题,在检查等式时忽略value

代码语言:javascript
复制
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,只需使用数组:

代码语言:javascript
复制
let remainingOptions = originalSet.symmetricDifference(ranked)

另一个选项:使用Filter

与使用SetsymmetricDifference不同,您可以使用mapranked数组中获取keys数组,然后在options数组上使用filter获取与这些keys不匹配的remaining选项

代码语言:javascript
复制
let rankedKeys = ranked.map { $0.key }
let remaining = options.filter { !rankedKeys.contains($0.key) }

这并不要求您从原始定义中更改Option结构。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56816650

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档