-1

I want to remove an element within a for-in loop if it fails a certain condition. Currently, there's a solution here, but it's old and seems complicated for all I'm trying to do.

In Java, I can just reference the index like so:

/* Program that removes negative numbers from an array */
//Make an array list and add some numbers to it.
ArrayList<Int> a = new ArrayList<Int>;
for (int i = 0; i < 10; i++){
    a.add( (int) ((Math.random - 0.5) * 100) //Add 10 numbers that are pos/neg.

//Remove all the negative numbers.
for (int i = 0; i < a.size; i++){
    if (a.get(i) < 0){
        a.remove(i); //Removes the element. 
    }
}

But in Swift, to my understanding, I have to use a for-each loop equivalent:

    var array = [-4, -2, 0, 4, 6, 7, 2, 5, 7]
    //Iterate looking for numbers < 0.
    for item in array{
        if (item < 0){
            array.removeAt(item) //ERROR 
        }
        else{
            //Right now, I just copy every value into a new array.
            //But I shouldn't even need this w/ the Arrays collection.
    }

How can I do this more simply? Sorry I'm a newbie here; thanks for your help!


Edit | Clarification June 14, 2020 at 11:44 PM:

 

Someone suggested filter which is a stellar response, but not what I was looking for. (My bad, sorry). I used this as an example for a different challenge I'm working on here while I learn Swift.

Please help me look for solutions that remove an element. Thank you!!

Mike Chase
  • 19
  • 6
  • You can just remove it. It’s ok to mutate the sequence you are iterating, because it’s a copy. – matt Jun 15 '20 at 03:48
  • possible duplicate of https://stackoverflow.com/a/52067229/2303865 – Leo Dabus Jun 15 '20 at 04:09
  • As it stands, your question is a duplicate. If `filter` or `removeAll(where:)` does not what you are looking for then please [edit] your question and updated with a clear description of the problem. – Martin R Jun 15 '20 at 06:38

2 Answers2

1

Use the removeAll(where:) method like this:

array.removeAll(where: { $0 < 0 })

or:

array.removeAll { $0 < 0 }
Frankenstein
  • 15,732
  • 4
  • 22
  • 47
1

Expanding on the possible duplicate question link I have commented above, you can extend SignedInteger protocol and create a property to return a Boolean value based on a condition. Then you can use it as a keyPath on RangeReplaceableCollection method that removes all the elements that satisfy the given predicate.

extension SignedInteger {
    var isNegative: Bool { self < 0 }
    var isPositive: Bool { self > 0 }
}

extension Numeric {
    var isZero: Bool { self == .zero }
}

var array = [-4, -2, 0, 4, 6, 7, 2, 5, 7]

array.removeAll(where: \.isNegative)
array  // [0, 4, 6, 7, 2, 5, 7]

array.removeAll(where: \.isZero)
array  // [4, 6, 7, 2, 5, 7]

array.removeAll(where: \.isPositive)
array  // []
Leo Dabus
  • 229,809
  • 59
  • 489
  • 571