2014-06-28 16 views
56

Esiste una contropartita in Swift a flatten in Scala, Xtend, Groovy, Ruby e co?Appiattisci una matrice di array in Swift

var aofa = [[1,2,3],[4],[5,6,7,8,9]] 
aofa.flatten() // shall deliver [1,2,3,4,5,6,7,8,9] 

naturalmente potrei usare ridurre per questo, ma che palle po

var flattened = aofa.reduce(Int[]()){ 
    a,i in var b : Int[] = a 
    b.extend(i) 
    return b 
} 
+0

non è come utilizzare l'oggetto add di un array? –

+0

Non ho ancora controllato Swift stesso, ma in Haskell e F # è "concat" - quindi forse guardi qualcosa chiamato così? - Sono piuttosto ottimista sul fatto che questo sia lì da qualche parte (la maggior parte dei lang FP. * So * sulle monadi e questo è il binding di List) – Carsten

+0

sì in haskell è in realtà chiamato concat. –

risposta

223

Swift 3,0

reduce:

let numbers = [[1,2,3],[4],[5,6,7,8,9]] 
let reduced = numbers.reduce([], +) 

flatMap:

let numbers = [[1,2,3],[4],[5,6,7,8,9]] 
let flattened = numbers.flatMap { $0 } 

joined:

let numbers = [[1,2,3],[4],[5,6,7,8,9]] 
let joined = Array(numbers.joined()) 
+17

Sarebbe bello se l'OP lo avesse contrassegnato come corretto.La risposta canonica non dovrebbe essere "importare una biblioteca" quando c'è una linea concisa che funziona altrettanto bene (e immagino che sia più efficiente). – Charlesism

+2

Giusto per affermarlo più in generale, 'flatMap' è disponibile a partire da Swift 1.2. –

+2

Qual è la differenza tra 'join' (formalmente noto come' flatten') con 'flatMap'? È che mentre 'flatMap' si unisce, può anche mappare/trasformare le cose. ma qui nell'esempio non abbiamo davvero bisogno di es. restituiamo '$ 0' – Honey

2

Un'altra implementazione più generico di reduce,

let numbers = [[1,2,3],[4],[5,6,7,8,9]] 
let reduced = reduce(numbers,[],+) 

Questo compie la stessa cosa, ma può dare un quadro più chiaro ciò che sta accadendo in reduce .

Dalla documentazione di Apple,

func reduce<S : SequenceType, U>(sequence: S, initial: U, combine: (U, S.Generator.Element) -> U) -> U 

Descrizione

ritorno il risultato del più volte chiamare combinare con un valore accumulato inizializzato a iniziale e ogni elemento di sequenza, a sua volta .

3

questo ha funzionato per me:

let numbers = [[1, 2, 3], [4, 5, 6]] 
let flattenNumbers = numbers.reduce([], combine: +) 
24

Dal Swift 2.0 c'è flatten (o joined a Swift 3) Metodo implementato per CollectionType protocollo:

let numbers = [[1,2,3],[4],[5,6,7,8,9]] 
let flattened = Array(numbers.flatten()) 

In alcuni casi l'uso di flatten() può essere vantaggioso in quanto restituisce raccolta pigro anziché array, ma può sempre essere convertito in un array quando viene passato a Array().

+0

@chrisco, per favore, puoi approfondire come la mia risposta è errata e quali sono i criteri per "la risposta corretta più semplice"? Puoi per favore dire anche come cancellare una risposta potrebbe influenzare la domanda in qualche modo? –

+0

Prova a eseguire prima lo snippet: cosa pensi che faccia? Cosa fa in realtà? Qual era la domanda originale? La tua risposta è corretta? In caso contrario, sarebbe meglio cancellarlo per migliorare la chiarezza di questo post. Ho fatto lo stesso con le mie risposte sbagliate. –

+0

@chrisco ti ringrazio molto per i tuoi suggerimenti, ma eseguo snippet prima di pubblicarli ovunque. E la mia risposta è corretta in quanto restituisce esattamente gli stessi risultati richiesti dall'OP e utilizzando meno codice per quello. Ammetto che la mia risposta originale stava restituendo una raccolta pigra al posto di un array, sebbene non ci fossero restrizioni su questo nella domanda. Continuo a non pensare che la cancellazione di una risposta corretta migliori in alcun modo la qualità della domanda. –

Problemi correlati