简体   繁体   中英

Filter and sort swift array

I have a swift array which I want to filter, here is the array

let array = [apple,workshops,shopping,sports,parties,pantry,pen] 

I want to filter the array in such a way that the items beginning with the search string to appear before items that just contain the search string

So when i search for example p, then the results should be in some way

let array = [parties,pantry,pen,apple,workshops,shopping,sports] 

I tried this

tagSearchResults = tagSearchResults.filter({ (interestTag:InterestTag) -> Bool in
            let tmp: NSString = interestTag.tag
            let range = tmp.rangeOfString(searchText, options: NSStringCompareOptions.CaseInsensitiveSearch)
            return range.location != NSNotFound
        })

but this gives me all strings containing the search string.

So guys how can i do this

You can just write

 let result = words
    .filter { $0.contains(keyword) }
    .sorted { ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) }

Example

let words = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "cat", "house"]
let keyword = "p"
let result = words
    .filter { $0.contains(keyword) }
    .sorted { ($0.hasPrefix(keyword) ? 0 : 1) < ($1.hasPrefix(keyword) ? 0 : 1) }

// ["pen", "pantry", "parties", "apple", "workshops", "shopping", "sports"]

Try this. Firstly, it filters the array to remove those elements that do not contain the search string, then uses a custom sort to prefer items that start with the search string. In general, use the Cartesian approach of splitting a problem into smaller sub-problems, rather than try to solve it all in one step.

let searchString = "p"
let array = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "xyzzy"]

let filteredArray = array.filter({ $0.contains(searchString) })
filteredArray // drops xyzzy

let sortedArray = filteredArray.sorted(isOrderedBefore:  {
    switch ($0.hasPrefix(searchString), $1.hasPrefix(searchString)) {
    case (true, true):
        return $0 < $1
    case (true, false):
        return true
    case (false, true):
        return false
    case (false, false):
        return $0 < $1
    }

})
sortedArray // "pantry", "parties", "pen", "apple", "shopping", "sports", "workshops"] as required

Another way:

let searchString = "p"
let array = ["apple", "workshops", "shopping", "sports", "parties", "pantry", "pen", "xyzzy"]
let result = array.filter{$0.containsString(searchString)}
    .map{($0.hasPrefix(searchString) ? 0 : 1, $0)}
    .sort{$0 < $1}
    .map{$1}
print(result) //->["pantry", "parties", "pen", "apple", "shopping", "sports", "workshops"]

(I don't know why, but my Xcode took huge time to compile these lines. Believe this compiles and runs as expected eventually.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM