Nesneleri başka bir diziye dayalı bir diziden kaldırma

Bunun gibi iki dizim var:

var arrayA = ["Mike", "James", "Stacey", "Steve"]
var arrayB = ["Steve", "Gemma", "James", "Lucy"]

Gördüğünüz gibi, James ve Steve eşleşiyor ve bunları arrayA dan kaldırabilmek istiyorum. Bunu nasıl yazarım?

21

8 cevap

@francesco-vadicamo's answer in Swift 2/3/4+

 arrayA = arrayA.filter { !arrayB.contains($0) }
31
katma
Yine de ilk önce arrayB öğesini Set konumuna getirmelisiniz.
katma yazar BallpointBen, kaynak
Senin varmi? Daha önce Xcode 9.2'de (ve daha önce 9.0'de) yaptım ve çalışıyor. Sizin için uygun değilse, lütfen bir kod gösteriniz, ben de yardım etmeye çalışayım.
katma yazar Federico Zanetello, kaynak
@cleexiang cevabımda bir demo var, Swift 4 ile çalıştırabilirsiniz :)
katma yazar Federico Zanetello, kaynak
@BallpointBen Yanıtta bir demo bağlantısı ekledim: Gördüğünüz gibi, beklendiği gibi çalışıyor.
katma yazar Federico Zanetello, kaynak
@BallpointBen neden? OP'nin sorduğu şey bu değil
katma yazar Federico Zanetello, kaynak
bu swift4'de işe yaramaz
katma yazar cleexiang, kaynak
xcode denediniz mi?
katma yazar cleexiang, kaynak

En kolay yol yeni Set konteynerini kullanmaktır (Swift 1.2/Xcode 6.3'e eklenmiştir):

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)

Sonuç kümesini arrayA olarak yeniden atamak istiyorsanız, copy yapıcısını kullanarak yeni bir örnek oluşturun ve arrayA 'a atayın:

arrayA = Array(intersection)

Dezavantajı ise 2 yeni veri seti oluşturmanız gerektiğidir. kesiştiği 'in çağrıldığı örneğe mutasyona uğramadığını, yalnızca yeni bir küme döndürdüğünü unutmayın.

Toplama, çıkarma vb. Benzer yöntemler vardır, bunlara bir göz atabilirsiniz.

25
katma
Bunu gelmiş geçmiş en iyi cevap olarak buldum. Koduna bak. Setlerin kesişmesi ve çıkarılması, HER madde boyunca yinelemekten çok daha verimlidir. Ayrıca, Apple bunu daha kolay bir çözüm olarak önerir. Sadece Swift Dili kılavuzunu okuyun: developer.apple.com/kütüphane/içerik/belge/Swift/& hellip;
katma yazar Farini, kaynak
Swift 1.2'de bulunduğunu söylemeyi unuttum - Xcode 6.3 kullanmıyorsun
katma yazar Antonio, kaynak
@HenryBrown Evet benim hatam - substract kullanmalısın, udpated answer bakın. Daha fazla bilgiye ihtiyaç duyarsanız belgelerine bakın - başka yararlı yöntemler de var.
katma yazar Antonio, kaynak
Set ve back'e dönüştürmek elementlerin sırasını değiştirebilir, bu nedenle siparişi umursuyorsanız kullanmamalısınız.
katma yazar haawa, kaynak
Üzgünüm, farkettim, bu aslında yapmak istediğim şeyin tam tersini yapıyor, maç adlarını almak istiyorum, onlarla kalmamak? Bu benzer bir işlemle yapılabilir mi?
katma yazar Henry Brown, kaynak
Teşekkürler Bu bir tedavi çalıştı ve gerçekten basittir.
katma yazar Henry Brown, kaynak
Ahh Tamam, haklısın, bu gece güncellenip gidip geleceğim. Yardımınız için teşekkürler.
katma yazar Henry Brown, kaynak
Üzgünüm, Set'i daha önce hiç kullanmadım. Az önce oyun alanına düşürdüm ve şöyle diyor: Çözülmemiş tanımlayıcı 'Set' kullanımı . Daha fazla detay verebilir misiniz?
katma yazar Henry Brown, kaynak
Bu, yinelenen değerler için işe yaramaz.
katma yazar Ruiz, kaynak

Bunun gibi:

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"]
14
katma
Bu çözüm küçük diziler için oldukça iyi çalışıyor, ancak karmaşıklığının O (n ^ 2) olduğu göz önünde bulundurulmalı. Daha büyük diziler için, arrayA 'yi bir kümeye dönüştürmeyi ve bunu find için kullanmayı düşünürdüm - bu karmaşıklığı O (2n)' ye düşürmelidir.
katma yazar Antonio, kaynak
Bu doğru cevap olduğu ortaya çıktı, teşekkür ederim.
katma yazar Henry Brown, kaynak

Antonio'nun cevabına katılıyorum, ancak küçük dizi çıkarmaları için bunun gibi bir filtre kapatması da kullanabilirsiniz:

let res = arrayA.filter { !contains(arrayB, $0) }
10
katma
Bu güzel, çünkü siparişi koruyor
katma yazar Alexander, kaynak

matt ve freytag'ın çözümleri SADECE kopyaları açıklayan ve diğer cevaplardan daha fazla + 1 almak zorunda olanlardır.

İşte Swift 3.0'ın Matt'in cevabının güncellenmiş bir versiyonu:

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)
    }
}
9
katma

Bu eksi bir fonksiyon olarak da uygulanabilir:

func -( lhs:T, rhs:T ) -> T {

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

    return lhs
}

Şimdi kullanabilirsiniz

arrayA - arrayB
5
katma

Antonio tarafından belirtilen Array → Set → Array yöntemini kullanarak ve bir operatörün rahatlığıyla, freytag'ın belirttiği gibi, bunu kullanmaktan çok memnun oldum:

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

Dizinleri kullanarak öğeleri kaldır:

  1. Array of Strings and indexes

    let animals = ["cats", "dogs", "chimps", "moose", "squarrel", "cow"]
    let indexAnimals = [0, 3, 4]
    let arrayRemainingAnimals = animals
        .enumerated()
        .filter { !indexAnimals.contains($0.offset) }
        .map { $0.element }
    
    print(arrayRemainingAnimals)
    
    //result - ["dogs", "chimps", "cow"]
    
  2. Array of Integers and indexes

    var numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
    let indexesToRemove = [3, 5, 8, 12]
    
    numbers = numbers
        .enumerated()
        .filter { !indexesToRemove.contains($0.offset) }
        .map { $0.element }
    
    print(numbers)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    



Remove elements using element value of another array

  1. Arrays of integers

    let arrayResult = numbers.filter { element in
        return !indexesToRemove.contains(element)
    }
    print(arrayResult)
    
    //result - [0, 1, 2, 4, 6, 7, 9, 10, 11]
    
  2. Arrays of strings

    let arrayLetters = ["a", "b", "c", "d", "e", "f", "g", "h", "i"]
    let arrayRemoveLetters = ["a", "e", "g", "h"]
    let arrayRemainingLetters = arrayLetters.filter {
        !arrayRemoveLetters.contains($0)
    }
    
    print(arrayRemainingLetters)
    
    //result - ["b", "c", "d", "f", "i"]
    
1
katma