web-dev-qa-db-ja.com

Swiftで配列から要素を削除する方法

Appleの新しい言語Swiftで配列から要素を設定解除または削除するにはどうすればよいですか?

ここにいくつかのコードがあります:

let animals = ["cats", "dogs", "chimps", "moose"]

要素animals[2]を配列からどのように削除できますか?

182
Leopold Joy

letキーワードは、変更できない定数を宣言するためのものです。変数を変更したい場合は、代わりにvarを使用してください。

var animals = ["cats", "dogs", "chimps", "moose"]

animals.remove(at: 2)  //["cats", "dogs", "moose"]

元のコレクションを変更せずにそのまま使用できる代替方法としては、削除したい要素なしでfilterを使用して新しいコレクションを作成することです。

let pets = animals.filter { $0 != "chimps" }
240
mythz

与えられた

var animals = ["cats", "dogs", "chimps", "moose"]

最初の要素を削除

animals.removeFirst() // "cats"
print(animals)        // ["dogs", "chimps", "moose"]

最後の要素を削除

animals.removeLast() // "moose"
print(animals)       // ["cats", "dogs", "chimps"]

インデックスの要素を削除

animals.remove(at: 2) // "chimps"
print(animals)           // ["cats", "dogs", "moose"]

未知のインデックスの要素を削除

1要素のみ

if let index = animals.index(of: "chimps") {
    animals.remove(at: index)
}
print(animals) // ["cats", "dogs", "moose"]

複数の要素

var animals = ["cats", "dogs", "chimps", "moose", "chimps"]

animals = animals.filter(){$0 != "chimps"}
print(animals) // ["cats", "dogs", "moose"]

または代わりに

animals.index(of: "chimps").map { animals.remove(at: $0) }

ノート

  • 上記のメソッドは(filterを除く)その場で配列を変更し、削除された要素を返します。
  • マップフィルタのクイックガイドを減らす
  • 元の配列を変更したくない場合は、dropFirstまたはdropLastを使用して新しい配列を作成できます。

Swift 3に更新しました

150
Suragch

上記の答えは、あなたがあなたが削除したい要素のインデックスを知っていると仮定するようです。

多くの場合、配列内で削除したいオブジェクトへの reference を知っています。このような場合は、インデックスを至る所に渡す必要もなく、オブジェクト参照を直接操作するほうが簡単かもしれません。したがって、私はこの解決策を提案します。 identity演算子!==を使用します。これは、2つのオブジェクト参照が両方とも同じオブジェクトインスタンスを参照しているかどうかをテストするために使用します。

func delete(element: String) {
    list = list.filter() { $0 !== element }
}

もちろんこれはStringsにはうまくいきません。

148
Daniel

Swift 4: これは、フィルタリングなしで配列内の要素を削除するためのクールで簡単な拡張です。

   extension Array where Element: Equatable {

    // Remove first collection element that is equal to the given `object`:
    mutating func remove(object: Element) {
        guard let index = index(of: object) else {return}
        remove(at: index)
    }

}

使用法 :

var myArray = ["cat", "barbecue", "pancake", "frog"]
let objectToRemove = "cat"

myArray.remove(object: objectToRemove) // ["barbecue", "pancake", "frog"]

Intはジェネリック型なので、Elementのような他の型でも動作します。

var myArray = [4, 8, 17, 6, 2]
let objectToRemove = 17

myArray.remove(object: objectToRemove) // [4, 8, 6, 2]
24
Skaal

Swift4の場合:

list = list.filter{$0 != "your Value"}
17
user9060380

あなたはそれをすることができました。まずDogが実際に配列に存在することを確認してから削除します。 forが配列上で複数回発生する可能性があると思われる場合は、Dogステートメントを追加します。

var animals = ["Dog", "Cat", "Mouse", "Dog"]
let animalToRemove = "Dog"

for object in animals
{
    if object == animalToRemove{
        animals.removeAtIndex(animals.indexOf(animalToRemove)!)
    }
}

Dogが配列内に存在し、一度だけ発生したことが確実な場合は、次のようにしてください。

animals.removeAtIndex(animals.indexOf(animalToRemove)!)

文字列と数字の両方がある場合

var array = [12, 23, "Dog", 78, 23]
let numberToRemove = 23
let animalToRemove = "Dog"

for object in array
{

    if object is Int
    {
        // this will deal with integer. You can change to Float, Bool, etc...
        if object == numberToRemove
        {
        array.removeAtIndex(array.indexOf(numberToRemove)!)
        }
    }
    if object is String
    {
        // this will deal with strings
        if object == animalToRemove
        {
        array.removeAtIndex(array.indexOf(animalToRemove)!)
        }
    }
}
13
GuiSoySauce

Swiftの配列に関連する操作はほとんどありません

配列を作成

var stringArray = ["One", "Two", "Three", "Four"]

配列にオブジェクトを追加

stringArray = stringArray + ["Five"]

Indexオブジェクトから値を取得

let x = stringArray[1]

オブジェクトを追加

stringArray.append("At last position")

インデックスにオブジェクトを挿入

stringArray.insert("Going", atIndex: 1)

オブジェクトを削除

stringArray.removeAtIndex(3)

連結オブジェクト値

var string = "Concate Two object of Array \(stringArray[1]) + \(stringArray[2])"
12
Solid Soft

削除したい要素のインデックスがわからず、その要素がEquatableプロトコルに準拠している場合は、次の操作を実行できます。

animals.removeAtIndex(animals.indexOf("dogs")!)

Equatable protocol answerを参照してください。 indexOfObjectまたは適切なcontainsObjectをどのようにして作成しますか

9
Byron

インデックス配列を使って要素を削除する:

  1. 文字列とインデックスの配列

    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. 整数とインデックスの配列

    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]
    



他の配列の要素値を使って要素を削除する

  1. 整数の配列

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

    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"]
    
7
Krunal

Xcode 10以降、および WWDC 2018セッション223、 "Embracing Algorithms"によると、 ///////////////良い良い方法はmutating func removeAll(where predicate: (Element) throws -> Bool) rethrowsになる

アップルの例:

var phrase = "The rain in Spain stays mainly in the plain."
let vowels: Set<Character> = ["a", "e", "i", "o", "u"]

phrase.removeAll(where: { vowels.contains($0) })
// phrase == "Th rn n Spn stys mnly n th pln."

を参照してくださいAppleのドキュメント

そのため、OPの例では、動物を削除する[2]、 "chimps":

var animals = ["cats", "dogs", "chimps", "moose"]
animals.removeAll(where: { $0 == "chimps" } )
// or animals.removeAll { $0 == "chimps" }

この方法は、スケーリングがよく(線形対2次)、読みやすく、きれいなので、好ましいかもしれません。 Xcode 10以降でしか機能しないことを覚えておいてください。これを書いている時点では、これはベータ版です。

7
davidrynn

「未知のインデックスの要素を削除する」に対する@ Suragchの代替案について:

より強力なバージョンの "indexOf(element)"があり、それはオブジェクト自身の代わりに述語にマッチします。これは同じ名前ですが、myObjects.indexOf {$ 0.property = valueToMatch}によって呼び出されます。 myObjects配列で見つかった最初の一致項目のインデックスを返します。

要素がオブジェクト/構造体の場合は、そのプロパティの1つの値に基づいてその要素を削除します。たとえば、car.colorプロパティを持つCarクラスがあり、あなたのcarsArrayから "赤い"車を削除したいとします。

if let validIndex = (carsArray.indexOf{$0.color == UIColor.redColor()}) {
  carsArray.removeAtIndex(validIndex)
}

予見できることに、繰り返し/ whileループ内に上記のifステートメントを埋め込み、ループから「抜け出す」ためのフラグを設定するためにelseブロックをアタッチすることで、「すべての」赤い自動車を削除するようにこれを作り直すことができます。

5
ObjectiveTC

Array内の要素がArrayを実装していると仮定して、Equatableから要素を削除することに気を配る以下の拡張を思いつきました:

extension Array where Element: Equatable {

  mutating func removeEqualItems(item: Element) {
    self = self.filter { (currentItem: Element) -> Bool in
      return currentItem != item
    }
  }

  mutating func removeFirstEqualItem(item: Element) {
    guard var currentItem = self.first else { return }
    var index = 0
    while currentItem != item {
      index += 1
      currentItem = self[index]
    }
    self.removeAtIndex(index)
  }

}

使用法:

var test1 = [1, 2, 1, 2]
test1.removeEqualItems(2) // [1, 1]

var test2 = [1, 2, 1, 2]
test2.removeFirstEqualItem(2) // [1, 1, 2]
2
nburk

カスタムオブジェクトの配列がある場合は、次のように特定のプロパティで検索できます。

    if let index = doctorsInArea.indexOf({$0.id == doctor.id}){
        doctorsInArea.removeAtIndex(index)
    }

たとえば名前で検索したい場合

    if let index = doctorsInArea.indexOf({$0.name == doctor.name}){
        doctorsInArea.removeAtIndex(index)
    }
2
Abo3atef

これはそれをするべきです(テストされていません):

animals[2..3] = []

編集:そしてあなたはそれをvarではなくletにする必要があります、そうでなければそれは不変の定数です。

2
Analog File

私はVarunのものとほとんど同じようにこの拡張を使いますが、これ(下記)は万能です:

 extension Array where Element: Equatable  {
        mutating func delete(element: Iterator.Element) {
                self = self.filter{$0 != element }
        }
    }
0
user3206558

stringオブジェクトを削除するための拡張子

extension Array {
    mutating func delete(element: String) {
        self = self.filter() { $0 as! String != element }
    }
}
0
Varun Naharia