2015-03-04 1 views
1

valeurs plus complexes, le tri en fonction des valeurs clés d'un dictionnaire avec des doubles ou simples Ints fonctionne parfaitement bien selon l'exemple fourni here ....Tri Dictionnaires contenant à Swift

Mais qu'en est-dictionary- plus complexe structures?

J'ai un dictionnaire avec des valeurs de dictionnaire qui se composent chacune d'un tableau de doubles-tuples. (assez complexe, je sais ...). Et je voudrais trier les valeurs du dictionnaire en fonction de la somme des Second-Tuple-Array. (c'est-à-dire que tous les éléments de deuxième tuple forment un tableau et que ce tableau est récapitulé, puis trions les sommes de tableau en fonction de la plus petite valeur). Mais tout ça sans perdre d'informations sur la clé du dictionnaire. Le résultat de la méthode demandée doit renvoyer un tableau de clés en fonction du résultat trié "second-tuple-summed-up-array-results"

Voici mon "pauvre" procès pour ce problème: J'ai essayé de trier les clés en fonction des valeurs du premier-Tuple du tableau de tuples avec l'exemple Playground suivant (voir ci-dessous), mais il ne fonctionne pas encore ....

Cela fonctionne pour les types de base:

extension Dictionary { 
    func keysSortedByValue(isOrderedBefore:(Value, Value) -> Bool) -> [Key] { 
     return sorted(self) { 
      let (lk, lv) = $0 
      let (rk, rv) = $1 
      return isOrderedBefore(lv, rv) 
     }.map { (k,v) in k } 
    } 
} 

let dict = ["a":2, "c":1, "b":3] 
dict.keysSortedByValue(<) // result array of keys: ["c", "a", "b"] 
dict.keysSortedByValue(>) // result array of keys: ["b", "a", "c"] 

Mais dans mon cas plus complexe, il ne fonctionne pas:

var criteria_array1 = [(Double, Double)]() 
var criteria_array2 = [Double]() 
var criteria_dict1 = [String:[(Double, Double)]]() 
var criteria_dict2 = [String:[Double]]() 

// Random creation of two dictionaries with a complex value-structure... 
// Dictionary1: keys = Strings, values = array of Double-Tuples 
// Dictionary2: keys = Strings, values = array of Doubles 
for n in 1...5 { 
    let currentTopoString: String = "topo_\(n)" 
    for t in 0...14 { 
     let a: Double = Double(arc4random_uniform(1000)) 
     let b: Double = Double(Double(arc4random_uniform(1000))/1000) 
     criteria_array1 += [(a, b)] 
     criteria_array2 += [b] 
    } 
    criteria_dict1[currentTopoString] = criteria_array1 
    criteria_dict2[currentTopoString] = criteria_array2 
    criteria_array1.removeAll() 
    criteria_array2.removeAll() 
} 

// the two following instruction generate compiler errors.... 
// why ??????????? 
// How could a complex dictionary-value-structure be applied to a sortingMethod ?? 
criteria_dict1.keysSortedByFirstTupleValue(>) 
criteria_dict2.keysSortedByFirstTupleValue(>) 

Répondre

1

Il s'agit d'une question de mise en œuvre de la fonction isOrderedBefore de manière appropriée. Le simple fait de passer en > ne va pas le couper (même en supposant qu'il y ait eu une implémentation de > pour les tableaux de tuples, il ne ferait presque certainement pas la comparaison-de-sommation que vous recherchez).

Si je comprends correctement votre objectif, vous souhaitez trier les clés en fonction de la valeur de la somme de l'une des entrées de ligne dans un tableau de tuples?

donc quelque chose comme ceci:

criteria_dict1.keysSortedByValue { lhs, rhs in 
    // if you actually want to sort by sum of first element in tuple, 
    // change next.1 to next.0 
    let left_sum = reduce(lhs, 0) { total, next in total + next.1 } 
    let right_sum = reduce(rhs, 0) { total, next in total + next.1 } 
    return left_sum > right_sum 
} 

Ceci est tout à fait inefficace, puisque vous additionnant les tableau pour toutes les comparaisons - en pratique, vous pouvez memoize, ou peut-être repenser le problème en termes de structure de données différente si vous le faites beaucoup.

+0

Merci beaucoup pour votre aide à ce sujet! En général, je me demande (avec plusieurs tableaux) comment on peut exécuter les fonctions de tableau rapide (telles que mapper, filtrer, réduire - ou même posséder des fonctions de tableau) sur chacun de ces tableaux, puis trier les résultats de fonction et connaissant toujours le numéro de tableau depuis le début. C'est ainsi que j'ai eu l'idée d'utiliser un dictionnaire avec des valeurs sous forme de tableaux. Mais encore une fois, il y a peut-être une façon plus sophistiquée de faire fonctionner les fonctions de tableau, en filtrant et en sachant toujours de quelle matrice-clé provient le résultat trié. Des suggestions à ce sujet? – iKK