2015-04-13 22 views

Odpowiedz

13

tak:

var arrayA = ["Mike", "James", "Stacey", "Steve"] 
var arrayB = ["Steve", "Gemma", "James", "Lucy"] 
for word in arrayB { 
    if let ix = find(arrayA, word) { 
     arrayA.removeAtIndex(ix) 
    } 
} 
// now arrayA is ["Mike", "Stacey"] 
+1

Ta odpowiedź okazała się poprawną, dziękuję. –

+7

To rozwiązanie działa całkiem dobrze w przypadku małych tablic, ale należy pamiętać, że jego złożoność to O (n^2). W przypadku większych tablic rozważałabym konwersję 'tablicaA' do zestawu i użycie go dla' find' - które powinno zmniejszyć złożoność do O (2n) – Antonio

24

Najprostszym sposobem jest użycie nowego Set pojemnik (dodane w Swift 1.2/Xcode 6.3):

var setA = Set(arrayA) 
var setB = Set(arrayB) 

// Return a set with all values contained in both A and B 
let intersection = setA.intersect(setB) 

// Return a set with all values in A which are not contained in B 
let diff = setA.subtract(setB) 

Jeśli chcesz przypisać otrzymaną wartość arrayA, wystarczy utworzyć nową instancję za pomocą kopii konstruktor i przypisać ją do arrayA:

arrayA = Array(intersection) 

minusem jest to, że trzeba stworzyć 2 nowe zestawy danych. Należy zauważyć, że intersect nie mutuje instancji, do której jest wywoływana, po prostu zwraca nowy zestaw.

Istnieją podobne metody dodawanie, odejmowanie, itd., Można spojrzeć na nich

+0

Przepraszam, nigdy nie korzystałem Ustaw wcześniej. Właśnie rzuciłem to na plac zabaw i mówię: "Używanie nierozwiązanego identyfikatora" Set''. Czy możesz rozwinąć więcej? –

+0

Zapomniałem wspomnieć, że jest dostępne w wersji Swift 1.2 - zakładam, że nie używasz Xcode 6.3 – Antonio

+0

Ahh Ok, Zakładasz, że dobrze, będę aktualizować dziś wieczorem i spróbuję. Dzięki za pomoc. –

9

zgadzam się z odpowiedzią Antonio, jednak dla małych odejmowań tablicy można również użyć filtra zamknięcie takiego:

let res = arrayA.filter { !contains(arrayB, $0) } 
+0

To jest miłe, ponieważ zachowuje porządek zamawiania. – Alexander

4

ten może być zrealizowany jako func minus:

func -<T:RangeReplaceableCollectionType where T.Generator.Element:Equatable>(lhs:T, rhs:T) -> T { 

    var lhs = lhs 
    for element in rhs { 
     if let index = lhs.indexOf(element) { lhs.removeAtIndex(index) } 
    } 

    return lhs 
} 

Teraz można użyć

arrayA - arrayB 
25

@ odpowiedź francesco-vadicamo w Swift 2/3/4 +

arrayA = arrayA.filter { !arrayB.contains($0) } 
+0

Powinny zamieniać 'arrayB' w' Set 'pierwszy. – BallpointBen

+0

@BallpointBen dlaczego? to nie jest to, co OP zadał –

+0

@BallpointBen Dodałem link demo na odpowiedź: jak widać, działa zgodnie z oczekiwaniami. –

9

rozwiązań matowych i Freytag są jedynymi, które stanowią duplikaty i powinien otrzymywać więcej +1 niż inne odpowiedzi.

Oto zaktualizowana wersja odpowiedzi matowej dla Swift 3.0:

var arrayA = ["Mike", "James", "Stacey", "Steve"] 
var arrayB = ["Steve", "Gemma", "James", "Lucy"] 
for word in arrayB { 
    if let ix = arrayA.index(of: word) { 
     arrayA.remove(at: ix) 
    } 
} 
2

Stosując metodę Array → Set → Array wspomniany przez Antonio iz wygody operatora, jak Freytag wskazał, byłem bardzo zadowolony z użyciem tego:

// Swift 3.x 
func - <Element: Hashable>(lhs: [Element], rhs: [Element]) -> [Element] 
{ 
    return Array(Set<Element>(lhs).subtracting(Set<Element>(rhs))) 
} 
1

Oto same operacje z macierzy liczb całkowitych Swift 3

var array1 = [1, 2, 3, 4, 5, 6] 

var array2 = [1,5] 

var arrayResult = array1.enumerated() 
    .filter { !array2.contains($0.0 + 1) } 
    .map { $0.1 } 

print(arrayResult) 

[2, 3, 4, 6]


Kolejny sposób na osiągnięcie tego samego rezultatu:

1. Zastosowanie filtra

let arrayResult = array1.filter { element in 
    return !array2.contains(element) 
} 

2. Sortuj

array2.sorted(by: >).forEach { if $0 < self.array1.count { self.array1.remove(at: $0) } } 
Powiązane problemy