Reputation: 2573
I have an array of string and another string:
let array = ["one","two","three"]
let string = "one two three four five six seven"
What is a Swifty way of removing occurrences found in the array from the string? I tried a for loop, but wanted to see if filter would work in such a case?
Upvotes: 1
Views: 665
Reputation: 18581
The following is an efficient solution that replaces the occurrence of an element in array
, plus its surrounding spaces, with one space only:
let array = ["one","two","three"]
let str = " eight one four two three five six seven "
var result = ""
var i = str.startIndex
while i < str.endIndex {
var j = i
while j < str.endIndex, str[j] == " " {
j = str.index(after: j)
}
var tempo1 = ""
if i != j { tempo1 += str[i..<j] }
if j < str.endIndex { i = j } else {
result += tempo1
break
}
while j < str.endIndex, str[j] != " " {
j = str.index(after: j)
}
let tempo2 = String(str[i..<j])
if !array.contains(tempo2) {
result += tempo1 + tempo2
}
i = j
}
print(result) //␣␣eight␣four␣five␣␣␣six␣seven␣
The symbol ␣
represents a space.
Vadian's : 0.000336s
JP Aquino's : 0.000157s
Rob Napier's : 0.000147s
This Solution : 0.000028s
This is at least 5 times faster than any other solution.
If you don't want to remove spaces (since they're not part of the original array), then this will do:
let array = ["one","two","three"]
let str = "one two three four five six seven "
var result = ""
var i = str.startIndex
while i < str.endIndex {
var j = i
while j < str.endIndex, str[j] == " " {
j = str.index(after: j)
}
if i != j { result += str[i..<j] }
if j < str.endIndex { i = j } else { break }
while j < str.endIndex, str[j] != " " {
j = str.index(after: j)
}
let tempo = String(str[i..<j])
if !array.contains(tempo) {
result += tempo
}
i = j
}
print(result) //␣␣␣four five six seven␣
Upvotes: 2
Reputation: 4066
let array = ["one","two","three"]
let string = "one two three four five six seven"
//Convert string to array
var stringArray = string.components(separatedBy: " ")
//Remove elements from original array
stringArray = stringArray.filter { !array.contains($0) }
//Convert stringArray back to string
let finalString = stringArray.joined(separator: " ")
print(finalString)// prints "four five six seven"
Upvotes: 1
Reputation: 285064
In Swift 4.2 there is a removeAll(where:
API.
let array = ["one","two","three"]
let string = "one two three four five six seven"
var components = string.components(separatedBy: " ")
components.removeAll{array.contains($0)}
let result = components.joined(separator: " ") // "four five six seven"
Upvotes: 3
Reputation: 299345
I believe the kind of filter
expression you're thinking of is this:
let finalString = string
.split(separator: " ") // Split them
.lazy // Maybe it's very long, and we don't want intermediates
.map(String.init) // Convert to the same type as array
.filter { !array.contains($0) } // Filter
.joined(separator: " ") // Put them back together
Upvotes: 5