减少要在 Swift 中设置的数组
Reduce array to set in Swift
我正在尝试将对象数组缩减为 Swift 中的一个集合,这是我的代码:
objects.reduce(Set<String>()) { [=11=].insert(.URL) }
但是,我得到一个错误:
Type of expression is ambiguous without more context.
我不明白是什么问题,因为URL的类型肯定是String。有什么想法吗?
您不必缩减数组即可将其放入集合中;只需使用数组创建集合:let objectSet = Set(objects.map { [=10=].URL })
.
reduce()
方法需要一个 returns 组合值的闭包,而 Set
值的 insert()
方法会不是 return 而是它在现有集合中插入一个新元素。
为了使其正常工作,您需要执行以下操作:
objects.reduce(Set<String>()) {
[=10=].union(CollectionOfOne(.URL))
}
但以上是一些不必要的并发症。如果你有一个大数组,那将意味着在 Swift 遍历 objects
中的所有元素时要创建大量不断增长的集合。最好遵循@NRitH 的建议并使用 map()
因为这样可以一次性生成结果集。
Swift 1.0-2.x 仅:
如果您的对象上的 URL
是强类型 String
,您可以创建一个新的 Set<String>
对象并在具有映射数组的集合上使用 unionInPlace
:
var mySet = Set<String>()
mySet.unionInPlace(objects.map { [=10=].URL as String })
使用 Swift 5.1,您可以使用以下三个示例之一来解决您的问题。
#1。使用 Array
的 map(_:)
method and Set
's init(_:)
初始化程序
在最简单的情况下,您可以将初始数组映射到 url
s (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({ [=10=].url })
let urlSet = Set(urlArray)
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
#2。使用 Array
的 reduce(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<String>(), { (urls, object) in
urls.insert(object.url)
})
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
作为替代方案,您可以使用 Array
的 reduce(_:_:)
方法:
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<String>(), { (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
扩展
如有必要,您可以为 Array
创建一个 mapToSet
方法,该方法采用 transform
闭包参数和 returns Set
。下面的 Playground 代码展示了如何使用它:
extension Array {
func mapToSet<T: Hashable>(_ transform: (Element) -> T) -> Set<T> {
var result = Set<T>()
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({ [=13=].url })
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
我正在尝试将对象数组缩减为 Swift 中的一个集合,这是我的代码:
objects.reduce(Set<String>()) { [=11=].insert(.URL) }
但是,我得到一个错误:
Type of expression is ambiguous without more context.
我不明白是什么问题,因为URL的类型肯定是String。有什么想法吗?
您不必缩减数组即可将其放入集合中;只需使用数组创建集合:let objectSet = Set(objects.map { [=10=].URL })
.
reduce()
方法需要一个 returns 组合值的闭包,而 Set
值的 insert()
方法会不是 return 而是它在现有集合中插入一个新元素。
为了使其正常工作,您需要执行以下操作:
objects.reduce(Set<String>()) {
[=10=].union(CollectionOfOne(.URL))
}
但以上是一些不必要的并发症。如果你有一个大数组,那将意味着在 Swift 遍历 objects
中的所有元素时要创建大量不断增长的集合。最好遵循@NRitH 的建议并使用 map()
因为这样可以一次性生成结果集。
Swift 1.0-2.x 仅:
如果您的对象上的 URL
是强类型 String
,您可以创建一个新的 Set<String>
对象并在具有映射数组的集合上使用 unionInPlace
:
var mySet = Set<String>()
mySet.unionInPlace(objects.map { [=10=].URL as String })
使用 Swift 5.1,您可以使用以下三个示例之一来解决您的问题。
#1。使用 Array
的 map(_:)
method and Set
's init(_:)
初始化程序
在最简单的情况下,您可以将初始数组映射到 url
s (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({ [=10=].url })
let urlSet = Set(urlArray)
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
#2。使用 Array
的 reduce(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<String>(), { (urls, object) in
urls.insert(object.url)
})
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
作为替代方案,您可以使用 Array
的 reduce(_:_:)
方法:
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<String>(), { (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
扩展
如有必要,您可以为 Array
创建一个 mapToSet
方法,该方法采用 transform
闭包参数和 returns Set
。下面的 Playground 代码展示了如何使用它:
extension Array {
func mapToSet<T: Hashable>(_ transform: (Element) -> T) -> Set<T> {
var result = Set<T>()
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({ [=13=].url })
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"