中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Swift 中怎么進行多重條件排序

發布時間:2021-06-23 09:37:02 來源:億速云 閱讀:192 作者:chen 欄目:編程語言

這篇文章主要介紹“Swift 中怎么進行多重條件排序”,在日常操作中,相信很多人在Swift 中怎么進行多重條件排序問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Swift 中怎么進行多重條件排序”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

前言

在一個條件或者單個屬性上進行排序非常簡單, Swift 本身就有相關的功能。

下面是對 int 數組進行排序的例子:

let numbers = [3, 5, 6, 1, 8, 2]          let sortedNumbers = numbers.sorted { (lhs, rhs) in     return lhs < rhs }  // [1, 2, 3, 5, 6, 8]

但有時我們需要根據多個條件或屬性來進行排序。為了演示這一點,我們創建一個結構體來作為示例。

這里我們有一個簡單的 BlogPost  結構體,它包含帖子標題和兩個統計數據,即瀏覽次數pageView和會話持續時間sessionDuration。

struct BlogPost {     let title: String     let pageView: Int     let sessionDuration: Double }

Sample 數據:

extension BlogPost {     static var examples: [BlogPost] = [         BlogPost(title: "Alice", pageView: 1, sessionDuration: 3),         BlogPost(title: "Peter", pageView: 1, sessionDuration: 2),         BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1),         BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2),         BlogPost(title: "Abena", pageView: 4, sessionDuration: 10)     ] }

如果您想查看哪些文章表現良好,可以按照瀏覽次數對它們直接進行排序。但是很多帖子都不那么流行,頁面瀏覽量也一樣。在這種情況下,需要根據另一個條件或屬性來進行進一步的排序。

我們將在本文中討論這種多屬性排序。他們有各種各樣的方法來解決這個問題。我將展示沒有任何復雜概念的最基本的方法。一旦你了解了基本原理,你就可以隨心所欲地進階了。

什么是多條件排序

多條件排序是指我們比較第一個條件的排序,只有當第一個條件相等時,我們才轉到下一個條件。我們這樣做直到找到一個不相等的條件。

偽代碼如下所示:

let sortedObjects = objects.sorted { (lhs, rhs) in     for (lhsCriteria, rhsCriteria) in [(lhsCrtria1, rhsCriteria1), (lhsCrtria2, rhsCriteria2), (lhsCrtria3, rhsCriteria3), ... , (lhsCrtriaN, rhsCriteriaN)] { // <1>         if lhsCriteria == rhsCriteria { // <2>             continue         }         return lhsCriteria < rhsCriteria // <3>     } }

<1> 我們從最重要的一個(也就是第一個)開始,循環遍歷條件列表。

<2> 如果這個順序條件相等,我們不能根據它來決定順序,就跳到下一個條件。

<3> 如果我們可以根據條件決定兩個對象之間的順序,我們就停止并返回結果。

如果你很難理解偽代碼,不用擔心。我不是一個偽代碼專業作家。下面的例子應該更清楚一點。

按照兩個字段對object數組進行排序

我們使用前面提到的場景,我們希望根據表現對BlogPost進行排序。

我們的表現取決于頁面瀏覽次數pageView,如果瀏覽次數相同,我們再看sessionDuration。

下面是上一個例子中用到的BlogPost結構體和對應的sample數據。

struct BlogPost {     let title: String     let pageView: Int     let sessionDuration: Double }  extension BlogPost {     static var examples: [BlogPost] = [         BlogPost(title: "Alice", pageView: 1, sessionDuration: 3),         BlogPost(title: "Peter", pageView: 1, sessionDuration: 2),         BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1),         BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2),         BlogPost(title: "Abena", pageView: 4, sessionDuration: 10)     ] }

我們衡量表現的方法可以翻譯成下面這樣的代碼:

let popularPosts = BlogPost.examples.sorted { (lhs, rhs) in if lhs.pageView == rhs.pageView { // <1> return lhs.sessionDuration > rhs.sessionDuration }    return lhs.pageView > rhs.pageView // <2> }

<1>如果博客文章有相同的訪問次數,我們使用訪問時間。

<2>如果訪問次數不相等,我們可以直接根據訪問次數來排序(我們使用降序)

排序的結果:

[BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2.0),  BlogPost(title: "Abena", pageView: 4, sessionDuration: 10.0),  BlogPost(title: "Alice", pageView: 1, sessionDuration: 3.0),  BlogPost(title: "Peter", pageView: 1, sessionDuration: 2.0),  BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1.0)]

按照多個字段對object數組進行排序

不難發現,根據兩個條件來排序非常簡單。讓我們引入更多的條件。如果博客文章的表現相同,我們按照title排序。

添加更多的sample數據:

extension BlogPost {     static var examples2: [BlogPost] = [         BlogPost(title: "Zoo", pageView: 5, sessionDuration: 2),         BlogPost(title: "Alice", pageView: 1, sessionDuration: 3),         BlogPost(title: "Peter", pageView: 1, sessionDuration: 2),         BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1),         BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2),         BlogPost(title: "Abena", pageView: 4, sessionDuration: 10),         BlogPost(title: "Angero", pageView: 1, sessionDuration: 2)     ] }

兩個條件和三個條件沒什么區別,我們可以沿用相同的邏輯:

let popularPosts = BlogPost.examples2.sorted { (lhs, rhs) in     if lhs.pageView == rhs.pageView {         if lhs.sessionDuration == rhs.sessionDuration { // <1>             return lhs.title < rhs.title         }                  return lhs.sessionDuration > rhs.sessionDuration     }          return lhs.pageView > rhs.pageView }

<1>  我們添加了另一個if來檢查博客文章是否具有相同的會話持續時間,如果它們具有相同的頁面瀏覽次數和會話持續時間,則按標題對它們進行排序。

排序結果:

[BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2.0), BlogPost(title: "Zoo", pageView: 5, sessionDuration: 2.0), BlogPost(title: "Abena", pageView: 4, sessionDuration: 10.0), BlogPost(title: "Alice", pageView: 1, sessionDuration: 3.0), BlogPost(title: "Angero", pageView: 1, sessionDuration: 2.0), BlogPost(title: "Peter", pageView: 1, sessionDuration: 2.0), BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1.0)]

問題

我們可以對兩個和三個條件使用相同的邏輯。這里唯一的問題是,條件越多,需要的嵌套就越多。

這是一個多條件的例子,可能會導致pyramid of doom。

let popularPosts = BlogPost.examples2.sorted { (lhs, rhs) in     if lhs.pageView == rhs.pageView {         if lhs.sessionDuration == rhs.sessionDuration {              if lhs.nextCriteria == rhs.nextCriteria {                  if lhs.nextCriteria == rhs.nextCriteria {                      ....                 }                  ...             }              ...         }                  return lhs.sessionDuration > rhs.sessionDuration     }          return lhs.pageView > rhs.pageView }

按照N個字段對object數組進行排序

為了避免 pyramid of doom, 我們再看看之前的偽代碼:

let sortedObjects = objects.sorted { (lhs, rhs) in     for (lhsCriteria, rhsCriteria) in [(lhsCrtria1, rhsCriteria1), (lhsCrtria2, rhsCriteria2), (lhsCrtria3, rhsCriteria3), ... , (lhsCrtriaN, rhsCriteriaN)] {         if lhsCriteria == rhsCriteria {             continue         }          return lhsCriteria < rhsCriteria     } }

上面的代碼不是解決類似問題的唯一方式,不過關鍵思路是相似的。關鍵思路就是把多個條件打包到一個集合當中去遍歷。

extension BlogPost {     static var examples2: [BlogPost] = [         BlogPost(title: "Zoo", pageView: 5, sessionDuration: 2),         BlogPost(title: "Alice", pageView: 1, sessionDuration: 3),         BlogPost(title: "Peter", pageView: 1, sessionDuration: 2),         BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1),         BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2),         BlogPost(title: "Abena", pageView: 4, sessionDuration: 10),         BlogPost(title: "Angero", pageView: 1, sessionDuration: 2)     ] }  typealias AreInIncreasingOrder = (BlogPost, BlogPost) -> Bool // <1>      let popularPosts = BlogPost.examples2.sorted { (lhs, rhs) in         let predicates: [AreInIncreasingOrder] = [ // <2>         { $0.pageView > $1.pageView },         { $0.sessionDuration > $1.sessionDuration},         { $0.title < $1.title }     ]          for predicate in predicates { // <3>         if !predicate(lhs, rhs) && !predicate(rhs, lhs) { // <4>             continue // <5>         }                  return predicate(lhs, rhs) // <5>     }          return false }

<1>我聲明了一個別名 AreInIncreasingOrder 用來匹配排序閉包,這提高了我們對謂詞集合聲明的可讀性

<2> 我們聲明了一個謂詞集合

<3> 我們遍歷這個謂詞集合

<4> 這里是關鍵邏輯,我們想要檢查條件是否能決定博文順序。但是 AreInIncreasingOrder 返回了一個布爾值.  我們應該如何判斷他們是否相等? 在回答這個問題之前,我們先檢查一下 AreInIncreasingOrder 的定義。

AreInIncreasingOrder 是一個謂詞,他會在第一個參數能決定順序時返回 true 否則返回 false  。兩個變量只有在各自都不是升序時才相等。

這意味著無論我們的參數順序如何,謂詞都必須是 false。換言之 lhs.pageView < rhs.pageView 和  rhs.pageView < lhs.pageView必須等于false才能決定順序相等。這就是我們 !predicate(lhs, rhs)  && !predicate(rhs, lhs) 這句代碼的意思。

<5> 如果順序相等,那么 continue 到下一個謂詞。

<6> 如果順序不相等,那么我們可以用這個謂詞來排序。

排序結果:

[BlogPost(title: "Akosua", pageView: 5, sessionDuration: 2.0),  BlogPost(title: "Zoo", pageView: 5, sessionDuration: 2.0),  BlogPost(title: "Abena", pageView: 4, sessionDuration: 10.0),  BlogPost(title: "Alice", pageView: 1, sessionDuration: 3.0),  BlogPost(title: "Angero", pageView: 1, sessionDuration: 2.0),  BlogPost(title: "Peter", pageView: 1, sessionDuration: 2.0), BlogPost(title: "Kofi", pageView: 1, sessionDuration: 1.0)]

到此,關于“Swift 中怎么進行多重條件排序”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

西贡区| 隆化县| 隆昌县| 吉林省| 洪雅县| 舒城县| 广宗县| 日土县| 宣城市| 乌鲁木齐县| 当涂县| 永仁县| 获嘉县| 越西县| 榆中县| 平和县| 屯昌县| 苗栗县| 称多县| 离岛区| 临城县| 乐亭县| 九台市| 怀柔区| 罗城| 塘沽区| 葵青区| 吴旗县| 株洲市| 长汀县| 房产| 仁寿县| 宿迁市| 崇信县| 从化市| 太和县| 南宫市| 陆川县| 南和县| 乐清市| 鹿邑县|