Kotlin集合分組

集合的分組(Grouping)

在之前的學習中,我們已經學會了如何對集合進行過濾、排序或執行聚合操作。

在本節中,我們將學習如何對集合元素進行分組,以便以最適合我們任務的方式呈現信息。


分組(Grouping)

在 Kotlin 中,有一些擴展函數可以用來對集合元素進行分組,其中一個就是 groupBy()。它接收一個 lambda 表達式,并返回一個 Map,其中的鍵(key)是分組依據,值(value)則是對應的集合元素組成的列表。

fun main() {val names = listOf("John", "Jane", "Mary", "Peter", "John", "Jane", "Mary", "Peter")// 按名字的首字母進行分組val groupedNames = names.groupBy { it.first() }println(groupedNames) // {J=[John, Jane, John, Jane], M=[Mary, Mary], P=[Peter, Peter]}
}

代碼解釋:
在上面的示例中,我們按名字的首字母進行分組:可以看到返回的 Map 中,鍵是名字的首字母,值是所有以該字母開頭的名字列表。例如,鍵 J 對應的值是 [John, Jane, John, Jane]


你還可以在 groupBy() 中傳入第二個 lambda 作為轉換函數(valueTransform)。這樣就能在分組時同時對元素進行變換。如下所示,我們將分組的元素轉換為大寫:

fun main() {val names = listOf("John", "Jane", "Mary", "Peter", "John", "Jane", "Mary", "Peter")// 按名字長度分組,并將每個名字轉為大寫fun main() {val names = listOf("John", "Jane", "Mary", "Peter", "John", "Jane", "Mary", "Peter")// 按名字長度分組,并將每個名字轉為大寫?val groupedNames2 = names.groupBy(keySelector = { it.length },valueTransform = { it.uppercase() })println(groupedNames2) // {4=[JOHN, JANE, MARY, JOHN, JANE, MARY], 5=[PETER, PETER]}
}val groupedNames2 = names.groupBy(keySelector = { it.length },              // 分組鍵:名字長度valueTransform = { it.uppercase() }       // 值變換:轉為大寫)println(groupedNames2) // 輸出:{4=[JOHN, JANE, MARY, JOHN, JANE, MARY], 5=[PETER, PETER]}
}

分組與附加操作

有時我們想對所有分組同時進行某種操作。我們可以使用 groupingBy() 方法,它返回一個 Grouping 實例,允許以“懶方式”對各組進行操作(即在執行操作前不會真正構建分組)。

常見方法:
  • eachCount():計算每組中元素的數量,返回一個 Map,鍵是分組鍵,值是該組的元素數量。

  • fold():帶有初始值,從左到右依次將操作應用于累加器與每個元素。如果集合為空,返回初始值。
    可以提供一個 initialValueSelector 函數用于設置初始值。

    • .fold(initialValue) { acc, element -> ... }
  • reduce():從第一元素開始進行累加操作(沒有初始值),如果集合為空會拋出異常。可使用 reduceOrNull() 以防止異常。

    • .groupingBy { ... }.reduce { key, acc, element -> ... }
fun main() {val names = listOf("John", "Jane", "Mary", "Peter", "John", "Jane", "Mary", "Peter")// 按首字母分組,并統計每組數量val groupedNames3 = names.groupingBy { it.first() }.eachCount()println(groupedNames3) // {J=4, M=2, P=2}// 按首字母分組,累加每組中名字的總長度val groupedNames4 = names.groupingBy { it.first() }.fold(0) { acc, name -> acc + name.length }println(groupedNames4) // {J=16, M=8, P=10}// 按名字長度分組,保留每組中最長的名字val groupedNames5 = names.groupingBy { it.length }.reduce { _, acc, name -> if (name.length > acc.length) name else acc }println(groupedNames5) // {4=John, 5=Peter}
}

使用 aggregate() 聚合

使用 aggregate() 函數,可以對每個分組應用操作并返回結果。它提供了一種通用方式來執行分組操作(在 foldreduce 不滿足需求時)。
語法:

aggregate { key, accumulator: R?, element, first ->// 返回新的 accumulator(累積值)
}
  • key:當前分組的鍵,比如 J, M, P

  • accumulator:上一次累積的值,第一次為 null

  • element:當前正在處理的元素(比如 "John")。

  • first:是否是該組的第一個元素。

示例:

fun main() {val names = listOf("John", "Jane", "Mary", "Peter", "John", "Jane", "Mary", "Peter")// 使用 aggregate 獲取每組的元素數量val groupedNames6 = names.groupingBy { it.first() }.aggregate { _, accumulator: Int?, _, first ->if (first) 1 else accumulator!! + 1}println(groupedNames6) // {J=4, M=2, P=2}// 判斷每組中所有名字的長度是否都是偶數val groupedNames7 = names.groupingBy { it.first() }.aggregate { _, accumulator: Boolean?, element, first ->if (first) element.length % 2 == 0 else accumulator!! && element.length % 2 == 0}println(groupedNames7) // {J=true, M=true, P=false}
}

總結

在本節中,我們學習了如何使用 groupBygroupingBy 函數對集合中的元素進行分組。這是處理集合數據時非常重要的技能。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89443.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89443.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89443.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

阿里云ssh證書過期,如果更換并上傳到服務器

登錄阿里云平臺,在控制臺中找到“數字證書管理服務”進入頻道后,選擇“SSL證書管理”點擊“創建證書”,創建成功后,進入證書詳情頁選擇“下載”板塊,根據自身服務器類型,下載相應的證書即可服務器更新證書登…

【軟件系統架構】系列七:系統性能——計算機性能深入解析

目錄 一、什么是計算機性能? 二、計算機性能核心指標 1. CPU性能指標 2. 內存性能指標 3. 存儲子系統性能 4. 網絡性能指標 5. 系統資源使用與并發能力 三、性能瓶頸分析方法 四、計算機性能評測與對比 常見性能測試指標與工具: 五、計算機性…

基于現代R語言【Tidyverse、Tidymodel】的機器學習方法

機器學習已經成為繼理論、實驗和數值計算之后的科研“第四范式”,是發現新規律,總結和分析實驗結果的利器。機器學習涉及的理論和方法繁多,編程相當復雜,一直是阻礙機器學習大范圍應用的主要困難之一,由此誕生了Python…

Python暑期學習筆記5

時間:2025.7.18學習內容:【語法基礎】while循環與循環嵌套一、循環語句循環流程圖二、while循環基本格式:while條件:循環體(條件滿足時段做的事情)改變變量死循環while True:循環體(要循環做的事…

world models and Human–Object Interaction (HOI)

Author: Chatgpt Here are several key research papers that explore the intersection of world models and Human–Object Interaction (HOI)—especially ones that build structured, object-centric representations from videos or use world-model-based learning to p…

無人值守共享自習室物聯系統安全防線:從設備到數據的全面防護策略!

在“全民學習”浪潮的推動下,無人值守共享自習室憑借24小時開放、靈活預約和沉浸式體驗,已成為城市學習空間的新形態。而當人力值守被物聯網設備替代后,安全風險卻從物理世界延伸到了數字世界。一套完整的自習室物聯網系統包含門禁、傳感器、…

【27】MFC入門到精通——MFC 修改用戶界面登錄IP IP Address Control

界面搭建 將【IP Address Control】控件,【Edit Control】控件和兩個【button】控件分別拖入主界面 將ID分別修改為:IDC_IP_ADDRESS IDC_IPADDRESS_EDIT IDC_GET_BUTTON IDC_CLEAN_BUTTON添加變量 為【IP Address Control】控件添加變量【m_IPaddress】&…

MacOS安裝linux虛擬機

在學習docker時用的云環境本身就是一個容器,啟動docker總是各種問題,所以直接在本機上裝一個虛擬機。 當前系統環境: 安裝虛擬機軟件 安裝UTM 下載官網:https://mac.getutm.app/ uname -m查看一下指令架構,下載…

TimSort:論Java Arrays.sort的穩定性

TimSort 是一種混合的、穩定的排序算法,結合了歸并排序(Merge Sort)和二分插入排序(Binary Insertion Sort)的優點,尤其適用于部分有序的數據。在 Java 中,Arrays.sort() 對對象數組排序時內部使…

企業數據生命周期安全架構設計

數據是企業的生命線,而安全則是這條生命線的保護神。今天我們就來聊聊如何為企業數據的一生一世構建一套堅不可摧的安全防護體系。 📚 文章目錄 為什么需要數據生命周期安全架構數據生命周期全景圖安全架構設計的核心原則各階段安全防護策略整體安全架構…

【Java】字符串常量池

文章目錄一.字符串常量池(StringTable)1.1 定義1.2 演示示例1.3 intern方法一.字符串常量池(StringTable) 1.1 定義 字符串常量詞本質是一個固定大小的HashTable。當用一個字符串構造String對象時,首先會去StringTable中查看是否存在在字符串,如果存在…

數據通信與計算機網絡——模擬傳輸

主要內容數字到模擬轉換幅移鍵控ASK頻移鍵控FSK相移鍵控PSK正交振幅調制QAM模擬信號調制調幅AM調頻FM調相PM一、數字到模擬轉換數字信號需要低通通道,如果現實應用中只有帶通通道,只能選擇模擬信號進行傳輸。將數字數據轉換為帶通模擬信號,傳…

如何用Python并發下載?深入解析concurrent.futures 與期物機制

concurrent.futures模塊的核心價值 Python的concurrent.futures模塊提供了線程池(ThreadPoolExecutor)和進程池(ProcessPoolExecutor)兩種并發模型,通過高層接口簡化并發編程。其核心優勢在于: 自動管理資源…

MMKV 存儲json list數據(kotlin)

1、添加依賴與初始化 首先在 build.gradle 中添加 MMKV 依賴: implementationcom.tencent:mmkv:1.2.12 在 Application 類中初始化 MMKV: import android.app.Application import com.tencent.mmkv.MMKVclass MyApp : Application() { override fun onCreate() { super.o…

C++ -- STL-- stack and queue

////// 歡迎來到 aramae 的博客,愿 Bug 遠離,好運常伴! ////// 博主的Gitee地址:阿拉美 (aramae) - Gitee.com 時代不會辜負長期主義者,愿每一個努力的人都能達到理想的彼岸。1. stack的介紹和使用 2. queue的介紹…

信息論至AI實踐:交叉熵的原理全景與應用深度解析

1 定義與數學原理:從信息論到分布差異度量 交叉熵(Cross Entropy)是信息論中用于量化兩個概率分布差異的核心概念,由Claude Shannon的信息論發展而來。它測量了在相同事件集合上,使用估計的概率分布q對服從真實概率分…

WAF 能防御哪些攻擊?

WAF(Web 應用防火墻)是網站和Web應用的安全守門人,但很多用戶對其具體防御范圍一知半解。實際上,WAF 能針對性攔截多種網絡攻擊,從常見的注入攻擊到復雜的惡意爬蟲,覆蓋Web安全的核心威脅。本文詳解WAF的防…

閑庭信步使用圖像驗證平臺加速FPGA的開發:第二十二課——圖像直方圖統計的FPGA實現

(本系列只需要modelsim即可完成數字圖像的處理,每個工程都搭建了全自動化的仿真環境,只需要雙擊top_tb.bat文件就可以完成整個的仿真,大大降低了初學者的門檻!!!!如需要該系列的工程…

群暉中相冊管理 immich大模型的使用

相對于其他的相冊管理軟件,Immich的智能搜索和人臉識別功能是其優勢,通過應用機器學習模型,其智能搜索和人臉識別功能更為先進。 一、大模型的下載與安裝 網上有大佬提供了相關大模型的下載:https://url22.ctfile.com/d/58003522…

在 Windows 上使用 Docker 運行 Elastic Open Crawler

作者:來自 Elastic Matt Nowzari 了解如何使用 Docker 在 Windows 環境中運行 Open Crawler。 了解將數據攝取到 Elasticsearch 的不同方式,并深入實踐示例,嘗試一些新方法。 Elasticsearch 擁有大量新功能,助你為特定場景構建最…