Swift에서 배열에서 요소를 제거하는 방법


236

Apple의 새로운 언어 Swift에서 배열에서 요소를 설정 해제 / 제거하려면 어떻게해야합니까?

코드는 다음과 같습니다.

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

animals[2]배열에서 요소를 어떻게 제거 할 수 있습니까?

답변:


300

let키워드는 변경할 수없는 상수를 선언하는 것입니다. 변수를 수정하려면 var대신 다음을 사용해야 합니다.

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

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

원본 컬렉션을 변경하지 않고 변경하지 않는 대안은 filter다음과 같이 제거하려는 요소없이 새 컬렉션을 만드는 것입니다.

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

7
FYI : remove제거 된 요소를 반환합니다.let animal = animals.remove(at: 2)
2Toad

1
인덱스 만 기준으로 필터링 할 수 있습니까 ??
shaqir saiyed

@shaqirsaiyed 생각할 수있는 모든 술어를 필터링 할 수 있습니다. 예를 들어 "s"로 끝나는 모든 동물을 걸러 낼 수 있습니다.
Womble

동물 추가 = 애완 동물
Puji Wahono

197

주어진

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

알 수없는 색인의 요소 제거

하나의 요소 만

if let index = animals.firstIndex(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"]

노트

  • 위의 메소드는 배열을 제자리에서 수정하고 (제외 filter) 제거 된 요소를 반환합니다.
  • 맵 필터 감소에 대한 신속한 가이드
  • 원래 배열을 수정하지 않으려면 dropFirst또는 dropLast새 배열을 사용 하거나 만들 수 있습니다 .

스위프트 5.2로 업데이트


이 예제들 덕분에 알 수없는 인덱스의 요소 제거 > 여러 요소chimps && moose대해 예를 들어 제거 하기 위해 어떤 클로저를 작성 하시겠습니까? 다음과 다른 항목을 찾고 있습니다{$0 != "chimps" && $0 != "moose"}

161

위의 답변은 삭제하려는 요소의 색인을 알고 있다고 가정합니다.

종종 배열에서 삭제하려는 객체에 대한 참조 를 알고 있습니다. (예를 들어 배열을 반복하고 찾아낸 경우 등) 이러한 경우 인덱스를 어디서나 전달하지 않고도 객체 참조로 직접 작업하는 것이 더 쉬울 수 있습니다. 따라서이 솔루션을 제안합니다. 그것은 사용 신원 연산자 !== 는 두 개의 객체 참조가 모두 동일한 개체의 인스턴스를 참조하는지 여부를 테스트에 사용합니다.

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

물론 이것은 단지 Strings를 위해 작동하지 않습니다 .


23
이어야한다list = list.filter({ $0 != element })
크레이그 Grummitt

5
ID 연산자로 확인하려는 경우 아닙니다.
다니엘

3
array.indexOf({ $0 == obj })
jrc

2
다른 객체를 참조하는 list경우이 삭제는 새 배열을에 할당하므로 다른 배열 참조를 업데이트하지 않습니다 list. 이 방법으로 배열에서 삭제하면 미묘한 의미가 있습니다.
Crashalot

1
함수형 프로그래밍 패러다임은 불변의 객체에 의존합니다. 즉, 당신은 그들을 변경하지 않습니다. 대신 새 객체를 만듭니다. 삭제, 매핑, 축소 등이 수행하는 작업입니다. 리스트는 새로 생성 된 객체입니다. 위의 코드 스 니펫에서 새로 만든 객체를 나열하도록 다시 할당합니다. 함수형 프로그래밍을 따르는 방식으로 코드를 설계하기 때문에 저에게 효과적입니다.
Daniel

44

스위프트 5 : 필터링없이 배열에서 요소를 제거하는 시원하고 쉬운 확장입니다.

   extension Array where Element: Equatable {

    // Remove first collection element that is equal to the given `object`:
    mutating func remove(object: Element) {
        guard let index = firstIndex(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]

1
Element : Equatable part
Nicolas Manzini의

1
훌륭한. 단지 콘크리트 종류 :-( 프로토콜을 준수 할 수 있기 때문에 프로토콜 유형은 'Equatable'을 준수 할 수 - 당신은 같은 프로토콜의 목록을 시작하면 그것은 일을하지 않지만
AW101

22

Swift4의 경우 :

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

15

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], "침팬지":

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

이 방법은 확장 성이 좋고 (선형 대 2 차) 읽기 쉽고 깨끗하기 때문에 선호 될 수 있습니다. Xcode 10 이상에서만 작동하며 작성 당시 베타 버전입니다.


removeAll (where :)는 swift 4.2에서만 가능합니다
Vlad Pulichev

14

스위프트의 어레이와 관련된 몇 가지 작업

배열 만들기

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

14

그렇게 할 수 있습니다. 먼저 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)!)
        }
    }
}

배열에 문자열이 없으면 어떻게합니까?
Apqu

@apqu는 또 다른 업데이트를했다 '|| object == Int () '및'|| object == String () '불필요
GuiSoySauce

배열을 반복하면 효율성이 다시 높아집니다. , .compactMap .filter 확인
MLBDG


10

인덱스 배열을 사용하여 요소를 제거하십시오.

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

4
이것은 하나의 라이너 답변이며 더 나은 코딩과 빠른 실행에 훨씬 효율적입니다.
iOSDev

안녕 @Krunal-좋은 대답, 당신은 다음 질문을 볼 수 있습니까 (이미지 배열에서 이미지를 발표) : stackoverflow.com/questions/47735975/…
서버 프로그래머

6

"알 수없는 색인의 요소 제거"에 대한 @Suragch의 대안과 관련하여 :

"indexOf (element)"의 더 강력한 버전이 객체 자체 대신 술어와 일치합니다. 이름은 동일하지만 myObjects.indexOf {$ 0.property = valueToMatch}에 의해 호출됩니다. myObjects 배열에서 처음으로 일치하는 항목의 색인을 리턴합니다.

요소가 객체 / 구조 인 경우 속성 중 하나의 값을 기준으로 해당 요소를 제거 할 수 있습니다. 예를 들어, car.color 속성을 가진 Car 클래스가 있고 carsArray에서 "빨간색"자동차를 제거하려고합니다.

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

아마도 반복 / while 루프 내에 위의 if 문을 포함시키고 else 블록을 연결하여 루프에서 "break"플래그를 설정하여 "모든"빨간 자동차를 제거하기 위해이 작업을 다시 수행 할 수 있습니다.


6

스위프트 5

guard let index = orders.firstIndex(of: videoID) else { return }
orders.remove(at: index)

4

사용자 정의 객체 배열이있는 경우 다음과 같은 특정 속성으로 검색 할 수 있습니다.

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

또는 예를 들어 이름으로 검색하려면

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

3

이것은해야합니다 (테스트되지 않음) :

animals[2..3] = []

편집 : 당신은 그것을 var아닌 아닌 으로 만들어야합니다. let그렇지 않으면 불변 상수입니다.


5
기존 배열의 (하위) 범위를 사용하여 다른 배열을 만들 때 범위에는 3 개의 점이 있어야합니다. 위의 내용은 동물로 작성해야합니다 [2 ... 3]
zevij

3

구현 Array의 요소를 가정하고 에서 확장 요소를 처리하는 다음 확장을 생각해 냈습니다 .ArrayEquatable

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]

안녕 @ nburk-좋은 대답, 당신은 다음 질문을 볼 수 있습니까 (이미지 배열에서 이미지를 발표) : stackoverflow.com/questions/47735975/…
서버 프로그래머

1

String 객체를 제거하는 확장

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

강제로 풀면 충돌이 발생할 수 있으므로이 경우에는 피해야합니다.
user3206558

"돌연변이"기능은 무엇입니까?
AwesomeElephant8232

이 함수는 self (array)를 바꿀 것이라고 말했었다.
Varun Naharia

1

Varun과 거의 동일한이 확장을 사용하지만이 확장 (아래)은 범용입니다.

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

1

배열의 요소를 제거하기 위해 사용을 remove(at:), removeLast()removeAll().

yourArray = [1,2,3,4]

2 위치에서 값을 제거

yourArray.remove(at: 2)

배열에서 마지막 값을 제거

yourArray.removeLast()

세트에서 모든 멤버를 제거합니다

yourArray.removeAll()
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.