web-dev-qa-db-ja.com

フィルタと並べ替えSwift配列

フィルタリングしたいSwift配列があります、これが配列です

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

検索文字列で始まるアイテムが、検索文字列だけを含むアイテムの前に表示されるように配列をフィルタリングしたい

したがって、たとえばpを検索すると、結果は何らかの形で表示されます。

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

私はこれを試しました

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

しかし、これにより、検索文字列を含むすべての文字列が得られます。

だからみんなどうやってこれを行うことができますか

14
Ranjit

あなたはただ書くことができます

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

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"]
18
Luca Angeletti

これを試して。まず、配列をフィルタリングして検索文字列を含まない要素を削除し、カスタムソートを使用して検索文字列で始まるアイテムを優先します。一般に、問題をすべて1つのステップで解決しようとするのではなく、問題をより小さなサブ問題に分割するデカルトアプローチを使用します。

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
13
Grimxn

別の方法:

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"]

(理由はわかりませんが、私のXcodeはこれらの行をコンパイルするのに非常に時間がかかりました。これは最終的に期待どおりにコンパイルおよび実行されると信じています。)

3
OOPer