I have an array
var arr = ["car", "car", "bike", "bus", "car", "car", "car"]
When I try to filter :
var newArr = arr.filter { $0 != "car" }
It removes all 5 cars, I only need to remove 3
I want new array to be:
["bike", "bus", "car", "car"]
CodePudding user response:
You can simply add a counter and check the condition inside your filter predicate:
var arr = ["car", "car", "bike", "bus", "car", "car", "car"]
var counter = 3
var newArr = arr.filter {
if counter > 0, $0 == "car" {
counter -= 1
return false
}
return true
}
print(newArr)
This will print:
["bike", "bus", "car", "car"]
If you would like to implement a removeAll(where:) method with the option to limit the number of elements removed you can implement something like:
extension RangeReplaceableCollection {
mutating func removeAll(where predicate: ((Element) -> Bool), limitedTo counter: Int) {
var counter = counter
removeAll {
if counter > 0, predicate($0) {
counter -= 1
return true
}
return false
}
}
}
Usage:
var arr = ["car", "car", "bike", "bus", "car", "car", "car"]
arr.removeAll(where: { $0 == "car"}, limitedTo: 3)
print(arr) // "["bike", "bus", "car", "car"]\n"
CodePudding user response:
If you want to delete the first 3 elements only if the number of occurrences exceeds 3, then here a generic function that does what you need:
func removeExactly<T: Equatable>(
theFirst k: Int,
occurencesOf element: T,
from a: [T]
) -> [T] {
guard k >= 0 else {
fatalError("k has to be non-negative")
}
if k == 0 { return a }
let n = a.count
var indices = [Int]()
for i in 0..<n where a[i] == element {
indices.append(i)
if indices.count == k { break }
}
//Make sure that we've found k occurrences
if indices.count != k { return a }
//Join the array slices excluding the k first occurrences of element
indices.append(n)
var ans = Array(a[0..<indices[0]])
for j in 1..<indices.count {
let start = indices[j - 1] 1
let end = indices[j]
ans = a[start..<end]
}
return ans
}
Here are some test cases:
var arr = ["car", "car", "bike", "bus", "car", "car", "car"]
print(removeExactly(theFirst: 3, occurencesOf: "car", from: arr))
//["bike", "bus", "car", "car"]
print(removeExactly(theFirst: 10, occurencesOf: "car", from: arr))
//["car", "car", "bike", "bus", "car", "car", "car"]
print(removeExactly(theFirst: 1, occurencesOf: "bike", from: arr))
//["car", "car", "bus", "car", "car", "car"]
print(removeExactly(theFirst: 2, occurencesOf: "bike", from: arr))
//["car", "car", "bike", "bus", "car", "car", "car"]