Existe uma contrapartida em Swift para flatten
Scala, Xtend, Groovy, Ruby e companhia?
var aofa = [[1,2,3],[4],[5,6,7,8,9]]
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9]
é claro que eu poderia usar reduzir para isso, mas que meio que é uma porcaria
var flattened = aofa.reduce(Int[]()){
a,i in var b : Int[] = a
b.extend(i)
return b
}
Respostas:
Swift> = 3.0
reduce
:flatMap
:joined
:fonte
flatMap
está disponível a partir do Swift 1.2.joined
(formalmente conhecido comoflatten
) comflatMap
? Será que, enquantoflatMap
se junta, ele também pode mapear / transformar as coisas. mas aqui no exemplo que realmente não precisa, ou seja, voltamos$0
flatMap
vai quer achatar uma matriz 2D em uma matriz de 1D ou removenil
valores, mas não ambos. Ele determina o que fazer com base se a matriz de primeiro nívelElement
é uma matriz ou opcional - portanto, se você passar uma matriz 2D de opcionais (por exemplo[[Int?]]
), ela escolherá achatar para 1D (por exemplo[Int?]
) . Para achatar para 1-D e remover nils de segundo nível, você precisariaarray.flatMap { $0 }.flatMap { $0 }
. Em outras palavras, o nivelamento de dimensão é equivalenteArray(array.joined())
e o nivelamento de remoção nula é equivalentearray.filter{ $0 != nil }.map{ $0! }
.flatMap
ainda é apropriado para o uso descrito na pergunta (achatando uma matriz 2D para 1D).compactMap
é explicitamente para removernil
itens de uma sequência, como uma variante deflatMap
uma vez.[[Any]]
, aflatMap
simplesmente a transforma em um tipo de[Any]
([1, 2, 3, 4, [5, 6], 7, 8, 9]). E se aplicássemosflatMap
novamente, agiríamos de acordo com um 'Qualquer? type, onde o compilador não sabe mais se é um valor simples ou uma matriz em si.Em Swift biblioteca padrão não é
joined
função implementada para todos os tipos em conformidade comSequence
o protocolo (ouflatten
emSequenceType
antes Swift 3), que incluiArray
:Em certos casos, o uso de
joined()
pode ser benéfico, pois retorna uma coleção lenta em vez de uma nova matriz, mas sempre pode ser convertida em uma matriz quando passada para oArray()
inicializador, como no exemplo acima.fonte
FlattenBidirectionalCollection<Array<Array<Int>>>(_base: [[1, 2, 3], [4], [5, 6, 7, 8, 9]]))
. Seu argumento é válido, porém, de que você pode acessá-lo como uma matriz plana; portanto, parece que aCustomStringConvertable
implementação é enganosa. Seu snippet de código estava e ainda está faltando um teste.flatten()
foi renomeado parajoined()
Swift 4.x / 5.x
Apenas para adicionar um pouco mais de complexidade à matriz, se houver uma matriz que contenha uma matriz de matrizes,
flatMap
ela realmente falhará.Suponha que a matriz seja
O que
flatMap
oucompactMap
retorna é:Para resolver esse problema, podemos usar nossa lógica simples de loop + recursão
Então, chame essa função com a matriz fornecida
O resultado é:
Essa função ajudará a achatar qualquer tipo de matriz, considerando o caso
Int
aquiSaída do campo de jogos:
fonte
Swift 4.x
Esse uso de
flatMap
não é preterido e é feito para isso. https://developer.apple.com/documentation/swift/sequence/2905332-flatmapfonte
Editar: use em
joined()
vez disso:https://developer.apple.com/documentation/swift/sequence/2431985-joined
Resposta original:
fonte
Swift 4.2
Eu escrevi uma extensão de matriz simples abaixo. Você pode usar para achatar uma matriz que contém outra matriz ou elemento. diferente do método join ().
uso:
fonte
Outra implementação mais genérica de
reduce
,Isso realiza a mesma coisa, mas pode fornecer mais informações sobre o que está acontecendo
reduce
.Dos documentos da Apple,
Descrição
Retorne o resultado da chamada repetida de combinar com um valor acumulado inicializado para inicial e cada elemento da sequência , por sua vez.
fonte
Use of unresolved identifier 'reduce'
Resposta de @ RahmiBozdag modificada, 1. Os métodos em extensões públicas são públicos. 2. Método extra removido, pois o índice inicial será sempre zero. 3. Não encontrei uma maneira de incluir o compactMap por nulo e opcionais, porque o método T sempre é [Qualquer?], Todas as sugestões são bem-vindas.
fonte
Você pode nivelar a matriz aninhada usando o seguinte método:
fonte
Apple Swift versão 5.1.2 (swiftlang-1100.0.278 clang-1100.0.33.9)
Alvo: x86_64-apple-darwin19.2.0
fonte
Swift 5.1
Caso você também deseje valores de Dicionário:
fonte
flatten()
foi renomeado parajoined()
Swift 3 de acordo com SE-0133:https://github.com/apple/swift-evolution/blob/master/proposals/0133-rename-flatten-to-joined.md
fonte
matriz é [[myDTO]]?
No swift 5, você pode usar isso = Array (self.matrix! .Joined ())
fonte
fonte