9
votes

Swap Tabley Valeurs dans des indices spécifiques?

Je crée asynchrone NSURLConnections code> pour les images hors d'un tableau de dictionnaires, chacun avec leur propre URL de l'image:

var allPosts:Array<Dictionary<String, AnyObject>> = [
    ["imageURL": "http://i.imgur.com/aLsnGqn.jpg", "postTitle":"0"],
    ["imageURL": "http://i.imgur.com/vgTXEYY.png", "postTitle":"1"],
    ["imageURL": "http://i.imgur.com/OXzDEA6.jpg", "postTitle":"2"],
    ["imageURL": "http://i.imgur.com/ilOKOx5.jpg", "postTitle":"3"],
]

var lastIndex = 0
var threshold = 4
var activeConnections = Dictionary<NSURLConnection, Dictionary<String, AnyObject?>>()

func loadBatchInForwardDirection(){
    func createConnection(i: Int){
        allPosts[i]["calledIndex"] = i
        var post = allPosts[i]
        let imageURL = NSURL(string: post["imageURL"] as! String)
        if imageURL != nil {
            let request = NSMutableURLRequest(URL: imageURL!, cachePolicy: .ReloadIgnoringLocalCacheData, timeoutInterval: 60)
            let connection = NSURLConnection(request: request, delegate: self, startImmediately: true)
            if connection != nil {
                activeConnections[connection!] = post
            }
        }
    }
    let startingIndex = lastIndex;
    for (var i = startingIndex; i < startingIndex + threshold; i++){
        createConnection(i)
        lastIndex++
    }
}

func connection(connection: NSURLConnection, didReceiveData data: NSData) {
    if activeConnections[connection] != nil {
        let dataDict = activeConnections[connection]!["data"]
        if dataDict == nil {
            activeConnections[connection]!["data"] = NSMutableData(data: data)
        } else {
            (activeConnections[connection]!["data"] as! NSMutableData).appendData(data)
        }
    }
}

var loadedIndex = 0
func connectionDidFinishLoading(connection: NSURLConnection) {
    let loadedPost = activeConnections[connection]!
    activeConnections.removeValueForKey(connection)
    let data = loadedPost["data"] as? NSData
    let calledIndex = loadedPost["calledIndex"] as! Int
    println(calledIndex)

    swap(&allPosts[calledIndex], &allPosts[loadedIndex])
    //(allPosts[calledIndex], allPosts[loadedIndex]) = (allPosts[loadedIndex], allPosts[calledIndex])

    loadedIndex++
    done(loadedIndex)
}

func done(index: Int){
    if index == 4 {
        println()
        println("Actual: ")
        println(allPosts[0]["postTitle"] as! String)
        println(allPosts[1]["postTitle"] as! String)
        println(allPosts[2]["postTitle"] as! String)
        println(allPosts[3]["postTitle"] as! String)
    }
}

func applicationDidFinishLaunching(aNotification: NSNotification) {
    loadBatchInForwardDirection()
    println("Loaded: ")
}

func applicationWillTerminate(aNotification: NSNotification) {
    // Insert code here to tear down your application
}


13 commentaires

Votre Posts La définition n'est pas légale Swift. Est-ce votre code actuel? Quel problème voyez-vous? Est-ce que est vraiment un tableau Swift ou est-ce un nsarray ou nsdictionner défini une autre solution?


@Robnapier whoops, j'ai simplifié le tableau mais j'ai oublié les citations autour de la clé. Je vais écrire un cas de test qui, espérons-le, montrez le problème et que je le posterai lorsque j'aurai fini.


Pourquoi ne triez-vous pas simplement en spécifiant une fermeture à utiliser pour des comparaisons?


@ROBNAPIER a mis à jour le message avec un exemple de test de test. Je manque probablement quelque chose de stupide, mais il est devenu un de ces problèmes que je regarde depuis trop longtemps et rien n'aide!


@NEO est que tout mieux que d'utiliser échanger contre ou robot de tuples?


C'est ce que tu veux. Et fondamentalement ce que vous voulez, c'est trier. Au lieu d'écrire votre propre tri et d'entrer dans la confusion comme vous êtes maintenant, utilisez simplement une sorte de construction intégrée.


@NEO Un problème potentiel, cependant, est que le tableau a généralement des milliers de valeurs, mais seule une certaine partie de ce réseau doit être triée. Par exemple, au lieu de tri des articles 0 ... 999, il ne devrait que trier les points 4 ... 7.


Je comprends votre préoccupation, mais la plupart des algorithmes de tri sont très efficaces sur des listes déjà triées. Je ne sais pas quel algorithme utilise la fonction triée d'Apple, mais je ne pense pas qu'ils choisissent quelque chose d'inefficace. Avec votre échange, vous essayez d'obtenir la même chose.


@Neo mais la majorité des articles n'ont pas encore leur clé d'oldIndex parce qu'ils n'ont pas encore été chargés


Ensuite, triez une fois que tous les articles ont leurs oldIndex peuplés.


@neo ne peut pas, puisque la valeur est remplie lorsqu'une image se chargeait, elle permettrait de charger toutes les images, puis de trier.


Vous n'écrénez jamais la variable Loadedindex dans votre premier échantillon de code de tentative.


@NEO Je m'excuse, j'essayais simplement de montrer la structure de la matrice.


6 Réponses :


14
votes

Vous pouvez simplement affecter via des tuples: xxx pré>

mais quel problème avez-vous réellement avec swap code>? Les éléments suivants doivent fonctionner correctement: P>

swap(&xs[1], &xs[2])


1 commentaires

J'ai mis à jour la question avec un cas de test. La seule différence entre le téléchargement et le snippet ci-dessous est que le tableau ne dispose plus de la touche KeyIndex .



3
votes

Si vous pouvez modifier le type de valeur de Changeindex en chaîne, le code ci-dessous doit fonctionner

var posts = [
    ["url": "url0", "calledIndex": "0"],
    ["url": "url2", "calledIndex": "2"],
    ["url": "url3", "calledIndex": "3"],
    ["url": "url1", "calledIndex": "1"]
]

posts = sorted(posts, { (s1: [String:String], s2: [String:String]) -> Bool in
    return s1["calledIndex"] < s2["calledIndex"]
})


0 commentaires

2
votes

Vous pouvez simplement utiliser le tri sur la valeur appelée:

var posts = [
  ["url": "url0", "calledIndex": 0],
  ["url": "url2", "calledIndex": 2],
  ["url": "url1", "calledIndex": 1],
  ["url": "url3", "calledIndex": 3]
]


var sortedPosts = sorted(posts) { ($0["calledIndex"] as! Int) < ($1["calledIndex"] as! Int)}


1 commentaires

Comme mentionné dans les commentaires, seules les sections de la matrice auront toutefois la variable appelée spécifiée.



2
votes

Le problème est que l'échange des valeurs ne vous donne pas le bon ordre, car vous pouvez échanger une valeur déjà échangée. Par exemple, si vous recevez dans la commande 3,0,1,2, vous échangerez:

array_before   called_index   loaded_index   array_after
0, 1, 2, 3     0              3              3, 1, 2, 0
3, 1, 2, 0     1              0              1, 3, 2, 0
1, 3, 2, 0     2              1              1, 2, 3, 0
1, 2, 3, 0     3              2              1, 2, 0, 3


0 commentaires

2
votes

Cela s'est effectivement fini par être beaucoup plus facile que prévu. Étant donné que la poste actuellement chargée est détenue dans Activeconnections Code>, je peux simplement remplacer la valeur code> Allporosts code> à l'index chargé avec le poste actuellement chargé:

allPosts[loadedIndex] = loadedPost


0 commentaires

0
votes

dans SWIFT 4
protocol MutableCollection {
  /// Exchange the values at indices `i` and `j`.
  ///
  /// Has no effect when `i` and `j` are equal.
  public mutating func swapAt(_ i: Index, _ j: Index)
}


0 commentaires