Nisba
Nisba

Reputation: 3448

Find backward in string first substring that belongs to a set (regex?)

I have a set of string set and I would like to find the first occurrence of one string of set as a substring of a string string. I would like to search in the backward direction from position (an integer).

I have written a code that uses a for loop but I would like to be able to write it in a more compact way, maybe regex are needed.

Can you please help me?

EDIT. my temporary solution: currentPosition is an integer value given by a NSTextView, command is the string I am manipulating, what I am doing now is checking if the character after the one at currentPosition is " " or if it is the last of the string command. In such cases I extrapolate the substring of command that spaces from currentPosition to the nearest (in the backward direction) delimiter (defined in my code).

What in my question is called set here is an array of String and it is represented by separators, what was string here is command, and what was position here is currentPosition.

let currentPosition = self.selectedRange().location
let currentPositionIndex = command.index(command.startIndex,offsetBy: currentPosition)
if(currentPosition == command.characters.count || command[currentPositionIndex] == " ")  {
    let separatorsString = " .,:~/!+=\\;/?"
    let separators = separatorsString.characters
    //TODO: use regex in order to clean the code
    var nearestSeparatorPosition = command.startIndex
    outerloop: for i in stride(from: currentPosition - 1, to: -1, by: -1) {
        for separator in separators {
            let index = command.index(command.startIndex, offsetBy: i)
            if(command[index] == separator) {
                nearestSeparatorPosition = command.index(index, offsetBy: 1)
                break outerloop
            }
        }
    }
    Swift.print("current word index = (\(command.distance(from: command.startIndex, to: nearestSeparatorPosition)),\(command.distance(from: command.startIndex, to: currentPositionIndex)))")
    let currentWord = command.substring(with: nearestSeparatorPosition ..< currentPositionIndex) 

Upvotes: 1

Views: 140

Answers (1)

GetSwifty
GetSwifty

Reputation: 7746

I'm not sure if I have some things flipped around, but based un my understanding of your question this is what I would do:

func findFirstContaining(needle item: String, in haystack: [String]) -> String? {

    let stringRanges: [Range<String.Index>] = haystack.flatMap { return item.range(of: $0) } .sorted { $0.lowerBound < $1.lowerBound }
    if let range = stringRanges.first {
        return item.substring(with: range)
    }
    else {
        return nil
    }
}

let testSet: Set<String> = ["test", "string", "set"]

let needle = "this is a test"

// evaluates to "test"
let result = findFirstContaining(needle: needle, in: testSet.sorted())

let reversedResult = findFirstContaining(needle: needle, in: testSet.sorted().reversed())

This is probably inefficient, but I'm not exactly sure what problem you're trying to solve.

Upvotes: 2

Related Questions