arrays - array - swift 4 filter example
Reduzca la matriz para establecer en Swift (4)
Con Swift 5.1, puede usar uno de los tres ejemplos siguientes para resolver su problema.
# 1
Usando el método
map(_:)
Array
y el
init(_:)
Set
map(_:)
Set
En el caso más simple, puede asignar su matriz inicial a una matriz de
url
s (
String
) y luego crear un conjunto a partir de esa matriz.
El siguiente código de Playground muestra cómo hacerlo:
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
Usando el método
reduce(into:_:)
Array
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"
Como alternativa, puede usar el método
reduce(_:_:)
Array
:
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
Usar una extensión de
Array
Si es necesario, puede crear un método
mapToSet
para
Array
que tome un parámetro de cierre de
transform
y devuelva un
Set
.
El siguiente código de Playground muestra cómo usarlo:
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"
Estoy tratando de reducir una matriz de objetos a un conjunto en Swift y este es mi código:
objects.reduce(Set<String>()) { $0.insert($1.URL) }
Sin embargo, recibo un error:
Type of expression is ambiguous without more context.
No entiendo cuál es el problema, ya que el tipo de URL es definitivamente String. ¿Algunas ideas?
No tiene que reducir una matriz para ponerla en un conjunto;
simplemente cree el conjunto con una matriz:
let objectSet = Set(objects.map { $0.URL })
.
Si la
URL
en su objeto es una
String
fuertemente tipada, puede crear un nuevo objeto
Set<String>
y usar
unionInPlace
en el conjunto con la matriz asignada:
var mySet = Set<String>()
mySet.unionInPlace(objects.map { $0.URL as String })
reduce()
método
reduce()
espera un cierre que
devuelve
un valor combinado, mientras que los métodos
insert()
de valor de
Set
no devuelven nada, sino que inserta un nuevo elemento en el conjunto existente.
Para que funcione, deberá hacer algo como:
objects.reduce(Set<String>()) {
$0.union(CollectionOfOne($1.URL))
}
Pero lo anterior es una complicación un poco innecesaria.
Si tiene una gran variedad, eso significaría crear una gran cantidad de conjuntos cada vez mayores mientras Swift revisa todos los elementos de los
objects
.
Mejor siga los consejos de @NRitH y use
map()
ya que eso haría un conjunto resultante de una sola vez.