2015-06-10 19 views
8

Sto cercando di fare il seguente codice che trasforma una serie di tuple in un dizionario, ma sto ricevendo un errore di compilazione dicendo:Errore: il valore Immutabile trasmesso ridurre la funzione

Immutable value of type '[String : String]' only has mutating members named 'updateValue'

var array = [("key0", "value0"), ("key1", "value1")] 
var initial = [String: String]() 
var final = array.reduce(initial) { (dictionary, tuple) in 
    dictionary.updateValue(tuple.0, forKey: tuple.1) 
    return dictionary 
} 

Perché è che se iniziale è stato dichiarato come var? Ha a che fare con @noescape su firma di riduzione?

func reduce<U>(initial: U, combine: @noescape (U, T) -> U) -> U 

risposta

8

Si può semplicemente rendere il parametro dictionary mutabile facendolo precedere da var:

var final = array.reduce(initial) { (var dictionary, tuple) in 
            ^^^ 

Nota tuttavia che l'utilizzo di un nuovo dizionario reduce viene creata ad ogni iterazione, rendendo l'algoritmo molto inefficiente. Si potrebbe voler considerare l'utilizzo di un tradizionaleforeach ciclo

+0

Grazie mille! L'avvertenza è che non posso usare $ 0 se voglio cambiare la mutabilità su quegli scenari, giusto? –

+0

Immagino di sì ... Non sono a conoscenza di alcun metodo per renderlo un var (che non significa necessariamente che non sia possibile) – Antonio

+0

@RaphaelOliveira: Parte di [questa risposta] (http://stackoverflow.com/a/24219069/1187415) è un metodo di dizionario Dictionary che accetta una serie di tuple chiave/valore (e che utilizza anche un semplice ciclo). –

4

Sulla Swift 3:

var final = array.reduce(initial) { (dictionary, tuple) -> [String: String] in 
    var mutableDictionary = dictionary 
    //.... make changes with mutableDictionary 
    return mutableDictionary 
} 
2

Swift 4 ha una nuova variante:

var array = [("key0", "value0"), ("key1", "value1")] 
var initial = [String: String]() 
var final = array.reduce(into: initial) { dictionary, tuple in 
    dictionary[tuple.0] = tuple.1 
} 

Il che potrebbe essere espresso:

var array = [("key0", "value0"), ("key1", "value1")] 
let final: [String: String] = array.reduce(into: [:]){ $0[$1.0] = $1.1 } 
Problemi correlati