I am trying to reduce an array of objects to a set in Swift and this is my code:
objects.reduce(Set<String>()) { $0.insert($1.URL) }
However, I get an error:
Type of expression is ambiguous without more context.
I do not understand what the problem is, since the type of URL is definitely String. Any ideas?
You don't have to reduce an array to get it into a set; just create the set with an array: let objectSet = Set(objects. map { $0. URL }) .
Swift version: 5.6. The reduce() method iterates over all items in array, combining them together somehow until you end up with a single value.
Returns an array containing the non- nil results of calling the given transformation with each element of this sequence.
You don't have to reduce an array to get it into a set; just create the set with an array: let objectSet = Set(objects.map { $0.URL })
.
With Swift 5.1, you can use one of the three following examples in order to solve your problem.
Array
's map(_:)
method and Set
's init(_:)
initializerIn the simplest case, you can map you initial array to an array of url
s (String
) then create a set from that array. The Playground below code shows how to do it:
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
's reduce(into:_:)
methodstruct 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"
As an alternative, you can use Array
's reduce(_:_:)
method:
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
extensionIf necessary, you can create a mapToSet
method for Array
that takes a transform
closure parameter and returns a Set
. The Playground below code shows how to use it:
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"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With