example array arrays swift set reduce

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.