객체 배열을 Swift에서 세트로 줄이려고하는데 이것이 내 코드입니다.
objects.reduce(Set<String>()) { $0.insert($1.URL) }
그러나 오류가 발생합니다.
Type of expression is ambiguous without more context.
URL 유형이 확실히 String이기 때문에 문제가 무엇인지 이해하지 못합니다. 어떤 아이디어?
답변:
집합으로 만들기 위해 배열을 줄일 필요가 없습니다. 배열로 세트를 만듭니다 let objectSet = Set(objects.map { $0.URL })..
let objectSet = Set(objects.map { $0.URL }).
Swift 5.1에서는 문제를 해결하기 위해 다음 세 가지 예제 중 하나를 사용할 수 있습니다.
Array의 map(_:)방법 Set의 init(_:)초기화를가장 간단한 경우에는 초기 배열을 urls ( String) 배열에 매핑 한 다음 해당 배열에서 집합을 만들 수 있습니다. 아래 코드는 그 방법을 보여줍니다.
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"
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"
Array확장 사용필요한 경우, 당신은 만들 수 있습니다 mapToSet에 대한 방법 Array소요 transform폐쇄 매개 변수를과를 반환합니다 Set. 코드 아래의 플레이 그라운드는 사용 방법을 보여줍니다.
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({ $0.url })
dump(urlSet)
// ▿ 3 members
// - "git-scm.com"
// - "mozilla.org"
// - "gnu.org"
reduce()method는 결합 된 값 을 반환 하는 클로저를 기대 하지만 value의 insert()메서드는 Set아무것도 반환하지 않고 대신 기존 세트에 새 요소를 삽입합니다.
작동하게하려면 다음과 같은 작업을 수행해야합니다.
objects.reduce(Set<String>()) {
$0.union(CollectionOfOne($1.URL))
}
그러나 위의 내용은 약간의 불필요한 복잡성입니다. 큰 배열이 있다면 Swift가 objects. @NRitH의 조언을 따르고 map()한 번에 결과 세트를 만들 수 있으므로 사용하십시오 .
func reduce<T>(_ initial: T, @noescape combine combine: (T, Self.Generator.Element) throws -> T) rethrows -> T이 당신이 전달하는 것이 아니라고 생각합니다.