当前位置:  开发笔记 > IOS > 正文

减少要在Swift中设置的数组

如何解决《减少要在Swift中设置的数组》经验,为你挑选了3个好方法。

我试图将一个对象数组减少到Swift中的一个集合,这是我的代码:

objects.reduce(Set()) { $0.insert($1.URL) }

但是,我收到一个错误:

Type of expression is ambiguous without more context.

我不明白问题是什么,因为URL的类型绝对是String.有任何想法吗?



1> NRitH..:

您不必减少数组以将其放入集合中; 只需使用数组创建集合:let objectSet = Set(objects.map { $0.URL }).



2> Imanou Petit..:

使用Swift 5.1,您可以使用以下三个示例之一来解决您的问题。


#1。使用Arraymap(_:)方法和Setinit(_:)初始值设定项

在最简单的情况下,您可以将初始数组映射到urls(String)的数组,然后从该数组创建一个集合。下面的Playground代码显示了操作方法:

struct MyObject {
    let url: String
}

let objectArray = [
    MyObject(url: "mozilla.org"),
    MyObject(url: "gnu.org"),
    MyObject(url: "git-scm.com")
]

let urlArray = objectArray.map({ $0.url })
let urlSet = Set(urlArray)
dump(urlSet)
// ? 3 members
//   - "git-scm.com"
//   - "mozilla.org"
//   - "gnu.org"

#2。使用Arrayreduce(into:_:)方法
struct MyObject {
    let url: String
}

let objectArray = [
    MyObject(url: "mozilla.org"),
    MyObject(url: "gnu.org"),
    MyObject(url: "git-scm.com")
]

let urlSet = objectArray.reduce(into: Set(), { (urls, object) in
    urls.insert(object.url)
})
dump(urlSet)
// ? 3 members
//   - "git-scm.com"
//   - "mozilla.org"
//   - "gnu.org"

或者,您可以使用Arrayreduce(_:_:)方法:

struct MyObject {
    let url: String
}

let objectArray = [
    MyObject(url: "mozilla.org"),
    MyObject(url: "gnu.org"),
    MyObject(url: "git-scm.com")
]

let urlSet = objectArray.reduce(Set(), { (partialSet, object) in
    var urls = partialSet
    urls.insert(object.url)
    return urls
})
dump(urlSet)
// ? 3 members
//   - "git-scm.com"
//   - "mozilla.org"
//   - "gnu.org"

#3。使用Array扩展

如有必要,您可以mapToSet为此方法创建一个Array带有transform闭合参数并返回的方法Set。下面的Playground代码显示了如何使用它:

extension Array {

    func mapToSet(_ transform: (Element) -> T) -> Set {
        var result = Set()
        for item in self {
            result.insert(transform(item))
        }
        return result
    }

}

struct MyObject {
    let url: String
}

let objectArray = [
    MyObject(url: "mozilla.org"),
    MyObject(url: "gnu.org"),
    MyObject(url: "git-scm.com")
]

let urlSet = objectArray.mapToSet({ $0.url })
dump(urlSet)
// ? 3 members
//   - "git-scm.com"
//   - "mozilla.org"
//   - "gnu.org"



3> courteouselk..:

reduce()方法需要一个返回组合值的闭包,而value的insert()方法Set不会返回任何内容,而是将新元素插入到现有集合中.

为了使它工作,你需要做类似的事情:

objects.reduce(Set()) {
    $0.union(CollectionOfOne($1.URL))
}

但以上是一些不必要的复杂情况.如果你有一个大数组,这意味着要创建相当多的不断增长的集合,而Swift会覆盖所有元素objects.更好地遵循@NRitH的建议并使用,map()因为这样可以一次性生成结果集.

推荐阅读
sx-March23
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有