2015-08-18 9 views
6

Wie spalte ich ein Kartenspiel? Ich habe ein Array gemacht und einen zufälligen Kartenhändler, aber habe keine Ahnung, wie man das Deck teilt.Wie teilt man ein Array in Swift in zwei Hälften?

Vielen Dank für die Hilfe! Ich habe jetzt eine Arbeitskarten-App, hatte andere Probleme, aber sie wurden schnell gelöst.

+3

Check this out: http://swiftdoc.org/func/split/ –

Antwort

8

Sie können Index Bereich

let deck: [String] = ["J", "Q", "K", "A"] 

// use ArraySlice only for transient computation 
let leftSplit: ArraySlice<String> = deck[0 ..< deck.count/2] // "J", "Q" 
let rightSplit: ArraySlice<String> = deck[deck.count/2 ..< deck.count] // "K", "A" 

// make arrays from ArraySlice 
let leftDeck: [String] = Array(leftSplit) // "J", "Q" 
let rightDeck: [String] = Array(rightSplit) // "K", "A" 

EDIT: obige Code ist für Swift 2, vielleicht für Swift 3 ist ein bequemer Weg.

+1

Sie wahrscheinlich stattdessen separate Arrays haben wollen, ist 'ArraySlice'. So würde 'Array (leftSplit)' das gewünschte Ergebnis liefern. – Qbyte

11

Sie können eine Erweiterung machen, so dass es eine Anordnung von zwei Arrays zurückgeben kann, die Arbeit mit Ints, Streicher, etc:

extension Array { 
    func split() -> [[Element]] { 
     let ct = self.count 
     let half = ct/2 
     let leftSplit = self[0 ..< half] 
     let rightSplit = self[half ..< ct] 
     return [Array(leftSplit), Array(rightSplit)] 
    } 
} 

let deck = ["J", "Q", "K", "A"] 
let nums = [0, 1, 2, 3, 4] 

deck.split() // [["J", "Q"], ["K", "A"]] 
nums.split() // [[0, 1], [2, 3, 4]] 

Aber ein benanntes Tupel Rückkehr besser sogar, weil es erzwingt die Tatsache, dass Sie erwarten genau zwei Arrays als Ergebnis:

extension Array { 
    func split() -> (left: [Element], right: [Element]) { 
     let ct = self.count 
     let half = ct/2 
     let leftSplit = self[0 ..< half] 
     let rightSplit = self[half ..< ct] 
     return (left: Array(leftSplit), right: Array(rightSplit)) 
    } 
} 

let deck = ["J", "Q", "K", "A"] 

let splitDeck = deck.split() 
print(splitDeck.left) // ["J", "Q"] 
print(splitDeck.right) // ["K", "A"] 

Hinweis: Gutschriften geht an Andrei und Qbyte für die erste richtige Antwort geben, ich bin nur Informationen hinzufügen.

+0

Named Tupel ist definitiv der bessere Weg zu gehen. Es lässt den Compiler durchsetzen, dass Sie nur zwei Arrays erwarten – Asa

+0

Vereinbart. :) Ich habe den Wortlaut meiner Antwort nach deinem Kommentar etwas modifiziert. – Moritz

1

Sie können eine Erweiterung unter SequenceType erstellen und eine Funktion mit dem Namen divide erstellen.

Diese Funktion würde durch die Elemente der Sequenz iterieren, während diejenigen, die dem Prädikat entsprechen, in ein Array (slice) und diejenigen, die nicht in ein anderes Array passen (remainder), platziert werden.

Die Funktion gibt ein Tupel zurück, das slice und remainder enthält.

extension SequenceType { 

    /** 
    Returns a tuple with 2 arrays. 
    The first array (the slice) contains the elements of self that match the predicate. 
    The second array (the remainder) contains the elements of self that do not match the predicate. 
    */ 
    func divide(@noescape predicate: (Self.Generator.Element) -> Bool) -> (slice: [Self.Generator.Element], remainder: [Self.Generator.Element]) { 
     var slice:  [Self.Generator.Element] = [] 
     var remainder: [Self.Generator.Element] = [] 
     forEach { 
      switch predicate($0) { 
      case true : slice.append($0) 
      case false : remainder.append($0) 
      } 
     } 
     return (slice, remainder) 
    } 

} 

Dies ist ein Beispiel

let tuple = [1, 2, 3, 4, 5].divide({ $0 >= 3 }) 
tuple.slice  // [3, 4, 5] 
tuple.remainder // [1, 2] 
Verwandte Themen