前言 我們已經介紹了radash的相關信息和部分Array相關方法,詳情可前往主頁查看; 本篇我們繼續介紹radash中Array的相關方法; 下期我們將介紹解析radash中剩餘的 Array相關方法,並整理出Array方法使用目錄,包括文章說明和腦圖說明。 Radash的Array相關方法詳解 ...
前言
- 我們已經介紹了radash的相關信息和部分Array相關方法,詳情可前往主頁查看;
- 本篇我們繼續介紹radash中Array的相關方法;
- 下期我們將介紹解析radash中剩餘的 Array相關方法,並整理出Array方法使用目錄,包括文章說明和腦圖說明。
Radash的Array相關方法詳解
iterate:把一個函數迭代執行指定次數
- 使用說明
- 參數:迭代次數、每次迭代調用的函數、迭代初始值。
- 返回值:返回最終一次迴圈迭代的值。
- 使用代碼示例
import { iterate } from 'radash' const value = iterate( 4, (acc, idx) => { return acc + idx }, 0 ) // => 10
- 源碼解析
// 定義一個泛型函數 `iterate`,它接收三個參數: // `count` 是一個數字,表示迭代的次數; // `func` 是一個函數,它在每次迭代中被調用,接收當前值和迭代次數作為參數,並返回一個新的值; // `initValue` 是迭代的初始值,它的類型為泛型 `T`。 export const iterate = <T>( count: number, func: (currentValue: T, iteration: number) => T, initValue: T ) => { // 初始化一個變數 `value`,用於存儲當前的迭代值,起始值設置為 `initValue`。 let value = initValue // 使用一個 `for` 迴圈進行 `count` 次迭代。迴圈變數 `i` 從 1 開始,以確保迭代次數正確。 for (let i = 1; i <= count; i++) { // 在每次迭代中,調用函數 `func`,傳入當前的 `value` 和迭代次數 `i`, // 然後將 `func` 函數返回的新值賦給 `value`,以便在下一次迭代中使用。 value = func(value, i) } // 迴圈結束後,返回最終的迭代值 `value`。 return value }
- 方法流程說明:
- 接收
count
、func
和initValue
作為參數。 - 初始化變數
value
為initValue
。 - 進行
count
次迭代,每次迭代中調用func
函數,傳入當前的value
和迭代次數i
。 func
函數返回一個新值,這個新值成為下一次迭代的value
。- 迭代完成後,返回最後一次
func
函數調用的結果。
- 接收
- 方法流程說明:
last:輸出數組的最後一項,如果數組為空則輸出傳入的預設值
-
使用說明
- 參數:目標數組,或者空數組和預設值。
- 返回值:數組最後一項,如果數組為空則輸出傳入的預設值。
-
使用代碼示例
import { last } from 'radash' const fish = ['marlin', 'bass', 'trout'] const lastFish = last(fish) // => 'trout' const lastItem = last([], 'bass') // => 'bass'
-
源碼解析
// 定義一個泛型函數 `last`,它接收一個具有隻讀屬性的泛型數組 `array`, // 和一個可選的預設值 `defaultValue`,其類型可以是泛型 `T` 或 `null` 或 `undefined`,預設值為 `undefined`。 export const last = <T>( array: readonly T[], defaultValue: T | null | undefined = undefined ) => { // 如果數組存在且長度大於0,返回數組的最後一個元素。 // 否則,返回提供的預設值 `defaultValue`。 return array?.length > 0 ? array[array.length - 1] : defaultValue }
- 方法流程說明:
- 檢查傳入的數組
array
是否存在且長度大於0。 - 如果數組存在且不為空(長度大於0),則返回數組的最後一個元素
array[array.length - 1]
。 - 如果數組不存在或為空,返回
defaultValue
。 - 這個函數對於需要安全地訪問數組最後一個元素而不拋出錯誤的情況很有用,特別是在不確定數組是否為空的情況下。通過提供一個預設值,你可以避免在數組為空時訪問未定義的索引。如果沒有提供預設值,函數將預設返回
undefined
。
- 檢查傳入的數組
- 方法流程說明:
list:創建包含特定項的數組
- 使用說明
- 參數:start、end、值,步長。
- 返回值:從start開始遍歷到end,輸出一個數組,包含特定項(值)的數組。
- 使用代碼示例
import { list } from 'radash' list(3) // [0, 1, 2, 3] list(0, 3) // [0, 1, 2, 3] list(0, 3, 'y') // [y, y, y, y] list(0, 3, () => 'y') // [y, y, y, y] list(0, 3, i => i) // [0, 1, 2, 3] list(0, 3, i => `y${i}`) // [y0, y1, y2, y3] list(0, 3, obj) // [obj, obj, obj, obj] list(0, 6, i => i, 2) // [0, 2, 4, 6]
- 源碼解析
// 定義一個泛型函數 `list`,它接受一個預設類型參數 `T`,預設為 `number`。 // 函數接受四個參數:起始值或長度 `startOrLength`,可選的結束值 `end`, // 可選的值或映射函數 `valueOrMapper` 用於生成數組中的值,以及可選的步長 `step`。 export const list = <T = number>( startOrLength: number, end?: number, valueOrMapper?: T | ((i: number) => T), step?: number ): T[] => { // 使用 `Array.from` 方法來創建一個數組,它接受 `range` 生成器函數作為參數。 // `range` 函數根據提供的參數生成一個序列的值。 return Array.from(range(startOrLength, end, valueOrMapper, step)) }
- 方法流程說明:
- 調用
range
函數,傳入startOrLength
(起始值或長度)、end
(結束值)、valueOrMapper
(值或映射函數)、step
(步長)四個參數。這些參數都是可選的,除了startOrLength
必須提供。 range
函數是一個生成器,根據提供的參數生成一個數字序列。如果指定了end
,那麼startOrLength
作為起始值,end
作為結束值。如果沒有指定end
,startOrLength
作為序列的長度。valueOrMapper
可以是一個值,此時序列中的每個元素都是這個值;也可以是一個函數,此時序列中的每個元素都是這個函數的返回值。step
指定了序列中每個元素之間的間隔。Array.from
方法用於從range
生成器創建一個數組。生成器的每次迭代返回的值都會成為數組中的一個元素。- 最終,
list
函數返回這個數組。
- 調用
- 方法流程說明:
max:獲取對象數組中指定標識符最大的項
- 使用說明
- 參數:目標對象數組、指定標識符的回調函數。
- 返回值:符合條件的對象。
- 使用代碼示例
import { max } from 'radash' const fish = [ { name: 'Marlin', weight: 105, source: 'ocean' }, { name: 'Bass', weight: 8, source: 'lake' }, { name: 'Trout', weight: 13, source: 'lake' } ] max(fish, f => f.weight) // => {name: "Marlin", weight: 105, source: "ocean"}
- 源碼解析
// 定義一個泛型函數 `max`,它接受一個具有隻讀屬性的泛型數組 `array`, // 以及一個可選的函數 `getter`,該函數用於從數組元素中提取一個數字用於比較大小。 export function max<T>( array: readonly T[], getter?: (item: T) => number ): T | null { // 如果 `getter` 函數未提供,則使用預設函數,它將元素作為其自己的值。 const get = getter ?? ((v: any) => v) // 調用 `boil` 函數,傳入數組和一個比較函數, // 比較函數用 `get` 函數獲取的值來決定哪個元素更大。 return boil(array, (a, b) => (get(a) > get(b) ? a : b)) } // 定義一個泛型函數 `boil`,它接受一個具有隻讀屬性的泛型數組 `array`, // 以及一個比較函數 `compareFunc`,該函數用於比較兩個元素並返回其中一個。 export const boil = <T>( array: readonly T[], compareFunc: (a: T, b: T) => T ) => { // 如果傳入的數組不存在,或者其長度為0,則返回 null。 if (!array || (array.length ?? 0) === 0) return null // 使用數組的 `reduce` 方法應用 `compareFunc`,將數組歸約為單一的值。 return array.reduce(compareFunc) }
- 方法流程說明:
- 接收一個數組
array
和一個可選的getter
函數。如果getter
函數提供,它將用於從每個元素中提取用於比較的數字值。 - 如果沒有提供
getter
函數,使用一個預設的函數,這個函數簡單地返回元素本身作為比較值。 - 調用
boil
函數,傳入數組和一個比較函數。這個比較函數使用get
函數從兩個元素a
和b
中提取值,並返回較大值對應的元素。 boil
函數通過reduce
方法遍曆數組,應用比較函數,並最終返回單一的元素,即數組中的最大元素。如果數組為空或未定義,boil
函數返回null
。max
函數最終返回boil
函數的結果,即數組中的最大元素,如果數組為空,則返回null
。
- 接收一個數組
- 方法流程說明:
merge:合併數組中符合條件的項,並且會覆蓋第一個數組
-
使用說明
- 參數:數組1、數組2、條件函數。
- 返回值:合併覆蓋後的數組。
-
使用代碼示例
import { merge } from 'radash' const gods = [ { name: 'Zeus', power: 92 }, { name: 'Ra', power: 97 } ] const newGods = [ { name: 'Zeus', power: 100 } ] merge(gods, newGods, f => f.name) // => [{name: "Zeus" power: 100}, {name: "Ra", power: 97}]
-
源碼解析
export const merge = <T>( root: readonly T[], others: readonly T[], matcher: (item: T) => any ) => { if (!others && !root) return [] if (!others) return root if (!root) return [] if (!matcher) return root return root.reduce((acc, r) => { const matched = others.find(o => matcher(r) === matcher(o)) if (matched) acc.push(matched) else acc.push(r) return acc }, [] as T[]) }
- 方法流程說明:
- 進行一系列的檢查,如果
others
和root
兩個數組都不存在或為空,或者沒有提供matcher
函數,就返回root
或者一個空數組。 - 使用
root
數組的reduce
方法構建最終的合併數組。在每次迭代中,使用matcher
函數檢查root
數組中的當前元素是否在others
數組中有匹配的元素。 - 如果在
others
數組中找到了一個匹配的元素,就把這個匹配的元素添加到累加器數組acc
中。 - 如果沒有找到匹配的元素,就把
root
數組中的當前元素添加到累加器acc
中。 - 繼續處理
root
數組的下一個元素,直到所有元素都被處理完畢。 - 返回累加器
acc
,它現在包含了合併後的元素。
- 進行一系列的檢查,如果
- 方法流程說明:
min:獲取對象數組中指定標識符最小的項
- 使用說明
- 參數:目標對象數組、指定標識符的條件函數。
- 返回值:符合條件的的項
- 使用代碼示例
import { min } from 'radash' const fish = [ { name: 'Marlin', weight: 105, source: 'ocean' }, { name: 'Bass', weight: 8, source: 'lake' }, { name: 'Trout', weight: 13, source: 'lake' } ] min(fish, f => f.weight) // => {name: "Bass", weight: 8, source: "lake"}
- 源碼解析
// 這是 `min` 函數的第一種聲明,它要求傳遞一個 `getter` 函數。 export function min<T>( array: readonly T[], getter: (item: T) => number ): T | null // 這是 `min` 函數的第二種聲明,它允許 `getter` 函數是可選的。 export function min<T>( array: readonly T[], getter?: (item: T) => number ): T | null { // 如果沒有提供 `getter` 函數,使用預設函數,它將元素作為其自己的值。 const get = getter ?? ((v: any) => v) // 調用 `boil` 函數,傳入數組和一個比較函數, // 比較函數用 `get` 函數獲取的值來決定哪個元素更小。 return boil(array, (a, b) => (get(a) < get(b) ? a : b)) }
- 方法流程說明:
- 函數接收一個數組
array
和一個可選的getter
函數。如果提供了getter
函數,它將用於從每個元素中提取用於比較的數字值。 - 如果沒有提供
getter
函數,則使用一個預設的函數,這個函數簡單地返回元素本身作為比較值。 - 調用
boil
函數,傳入數組和一個比較函數。這個比較函數使用get
函數從兩個元素a
和b
中提取值,並返回較小值對應的元素。 boil
函數通過reduce
方法遍曆數組,應用比較函數,並最終返回單一的元素,即數組中的最小元素。如果數組為空或未定義,boil
函數返回null
。min
函數最終返回boil
函數的結果,即數組中的最小元素,如果數組為空,則返回null
。
- 函數接收一個數組
- 方法流程說明:
objectify:根據函數映射的鍵與值把數組轉換為字典對象
- 使用說明
- 參數:目標對象數組、條件函數1用於提取鍵、[條件函數2用於提取值]
- 返回值:字典對象
- 使用代碼示例
import { objectify } from 'radash' const fish = [ { name: 'Marlin', weight: 105 }, { name: 'Bass', weight: 8 }, { name: 'Trout', weight: 13 } ] objectify(fish, f => f.name) // => { Marlin: [marlin object], Bass: [bass object], ... } objectify( fish, f => f.name, f => f.weight ) // => { Marlin: 105, Bass: 8, Trout: 13 }
- 源碼解析
// 定義一個泛型函數 `objectify`,它接受三個參數: // `array` 是一個具有隻讀屬性的泛型數組, // `getKey` 是一個函數,用於從數組元素中提取鍵, // `getValue` 是一個可選的函數,用於從數組元素中提取值,預設情況下,它會返回元素本身作為值。 export const objectify = <T, Key extends string | number | symbol, Value = T>( array: readonly T[], getKey: (item: T) => Key, getValue: (item: T) => Value = item => item as unknown as Value ): Record<Key, Value> => { // 使用數組的 `reduce` 方法來累積一個對象,該對象將數組元素映射為鍵值對。 return array.reduce((acc, item) => { // 使用 `getKey` 函數從當前元素 `item` 中提取鍵,並使用 `getValue` 函數提取值。 // 將這個鍵值對添加到累加器對象 `acc` 中。 acc[getKey(item)] = getValue(item) // 返回更新後的累加器 `acc`。 return acc }, {} as Record<Key, Value>) // 初始化累加器 `acc` 為一個空對象。 }
- 方法流程說明:
- 函數接收一個數組
array
,一個getKey
函數用於提取每個元素的鍵,以及一個可選的getValue
函數用於提取每個元素的值。 - 如果沒有提供
getValue
函數,則使用一個預設的函數,這個函數簡單地將元素本身作為值。 - 使用
reduce
方法遍曆數組。reduce
方法的累加器acc
是一個對象,用於存儲鍵值對。 - 對於數組中的每個元素
item
,使用getKey
函數提取鍵,並使用getValue
函數提取值。 - 將提取的鍵和值作為一個鍵值對添加到累加器對象
acc
中。 - 繼續處理數組的下一個元素,直到所有元素都被處理完畢。
- 返回累加器
acc
,它現在是一個完整的對象,包含了從數組元素映射而來的鍵值對。
- 函數接收一個數組
- 方法流程說明:
range:根據步長生成一個數值範圍內的迭代值
- 使用說明
- 參數:起始值、[結束值]、[迭代函數]、步長。
- 返回值:用在for迴圈中迴圈輸出處理的結果值。
- 使用代碼示例
import { range } from 'radash' range(3) // yields 0, 1, 2, 3 range(0, 3) // yields 0, 1, 2, 3 range(0, 3, 'y') // yields y, y, y, y range(0, 3, () => 'y') // yields y, y, y, y range(0, 3, i => i) // yields 0, 1, 2, 3 range(0, 3, i => `y${i}`) // yields y0, y1, y2, y3 range(0, 3, obj) // yields obj, obj, obj, obj range(0, 6, i => i, 2) // yields 0, 2, 4, 6 for (const i of range(0, 200, 10)) { console.log(i) // => 0, 10, 20, 30 ... 190, 200 } for (const i of range(0, 5)) { console.log(i) // => 0, 1, 2, 3, 4, 5 }
- 源碼解析
// 定義一個泛型生成器函數 `range`,它接受一個預設類型參數 `T`,預設為 `number`。 // 函數接受四個參數:起始值或長度 `startOrLength`,可選的結束值 `end`, // 可選的值或映射函數 `valueOrMapper` 用於生成序列中的值,以及可選的步長 `step`,預設為 1。 export function* range<T = number>( startOrLength: number, end?: number, valueOrMapper: T | ((i: number) => T) = i => i as T, step: number = 1 ): Generator<T> { // 確定 `valueOrMapper` 是一個函數還是一個固定值。如果是函數,則直接使用;如果不是,則創建一個總是返回該值的函數。 const mapper = isFunction(valueOrMapper) ? valueOrMapper : () => valueOrMapper // 如果提供了 `end` 值,則 `start` 為 `startOrLength`;如果沒有提供 `end` 值,則 `start` 預設為 0。 const start = end ? startOrLength : 0 // `final` 是序列的結束值,如果提供了 `end` 值,則使用它;如果沒有,則 `final` 為 `startOrLength`。 const final = end ?? startOrLength // 從 `start` 開始,到 `final` 結束,每次迭代增加 `step`。 for (let i = start; i <= final; i += step) { // 使用 `yield` 關鍵字產生由 `mapper` 函數處理的當前迭代值 `i`。 yield mapper(i) // 如果下一次增加步長後的值會超過 `final`,則提前終止迴圈。 if (i + step > final) break } }
- 方法流程說明:
- 確定
valueOrMapper
參數是一個函數還是一個值。如果是函數,直接用作映射器;如果是值,創建一個總是返回該值的函數作為映射器。 - 確定起始值
start
。如果提供了end
參數,start
是startOrLength
;否則start
預設為 0。 - 確定結束值
final
。如果提供了end
參數,final
是end
;否則final
是startOrLength
。 - 使用一個
for
迴圈從start
遍歷到final
,每次迭代增加步長step
。 - 在每次迭代中,使用
yield
關鍵字來產出mapper
函數處理過的當前值。 - 如果在下一次迭代步長加上當前值
i
會超過final
,則提前退出迴圈。 - 提示:這個
range
函數提供了類似於 Python 中的range
函數的功能,允許在迭代中產生一系列的值。通過使用生成器,我們可以惰性地產生這些值,這意味著直到迭代器被消費時,這些值才會被計算和產生。這在處理大範圍的值時非常有用,因為它不需要一次性將所有值載入到記憶體中。
- 確定
- 方法流程說明:
replaceOrAppend:替換對象數組中的項或是追加項(條件函數不滿足時追加);
-
使用說明
- 參數:被替換數組、用來的替換的數組、條件函數。
- 返回值:替換或者追加後的數組。
-
使用代碼示例
import { replaceOrAppend } from 'radash' const fish = [ { name: 'Marlin', weight: 105 }, { name: 'Salmon', weight: 19 }, { name: 'Trout', weight: 13 } ] const salmon = { name: 'Salmon', weight: 22 } const sockeye = { name: 'Sockeye', weight: 8 } replaceOrAppend(fish, salmon, f => f.name === 'Salmon') // => [marlin, salmon (weight:22), trout] replaceOrAppend(fish, sockeye, f => f.name === 'Sockeye') // => [marlin, salmon, trout, sockeye]
-
源碼解析
// 定義一個泛型函數 `replaceOrAppend`,它接受三個參數: // `list` 是一個具有隻讀屬性的泛型數組, // `newItem` 是一個新的元素,將被添加到數組中, // `match` 是一個函數,用於確定新元素應該替換數組中的哪個現有元素。 export const replaceOrAppend = <T>( list: readonly T[], newItem: T, match: (a: T, idx: number) => boolean ) => { // 如果 `list` 和 `newItem` 都不存在或為空,則返回一個空數組。 if (!list && !newItem) return [] // 如果 `newItem` 不存在或為空,則返回 `list` 數組的副本。 if (!newItem) return [...list] // 如果 `list` 不存在或為空,則返回一個只包含 `newItem` 的數組。 if (!list) return [newItem] // 遍歷 `list` 數組,尋找一個匹配的元素。 for (let idx = 0; idx < list.length; idx++) { const item = list[idx] // 如果 `match` 函數返回 `true`,則在該位置替換元素。 if (match(item, idx)) { // 創建一個新數組,其中包含從 `list` 開始到匹配位置之前的所有元素, // 然後是 `newItem`,然後是從匹配位置之後到 `list` 結束的所有元素。 return [ ...list.slice(0, idx), newItem, ...list.slice(idx + 1, list.length) ] } } // 如果沒有找到匹配的元素,將 `newItem` 追加到 `list` 數組的末尾。 return [...list, newItem] }
- 方法流程說明:
- 進行一系列的檢查,如果
list
和newItem
都不存在或為空,或者只有newItem
不存在或為空,或者只有list
不存在或為空,則返回相應的結果。 - 如果
list
和newItem
都存在,遍歷list
數組,對於每個元素和它的索引,調用match
函數。 - 如果
match
函數對某個元素返回true
,說明找到了應該被替換的元素。函數將創建一個新數組,該數組由以下部分組成:從list
的開始到匹配元素之前的部分,newItem
,以及從匹配元素之後到list
結尾的部分。 - 如果遍歷完成後沒有找到任何匹配的元素,函數將
newItem
添加到list
的末尾,並返回新數組。
- 進行一系列的檢查,如果
- 方法流程說明:
下期我們將介紹 radash 中剩餘的數組相關方法
- replace :查找指定項,並用傳入的去替換;
- select :對數組同時進行過濾和映射,輸出映射後的value數組;
- shift :把目標數組向右移動 n 個位置返回為一個新數組;
- sift:過濾調列表中值為false的項,返回剩餘為true的項組成的數組;
- sort :把數組按照條件函數指定的項的數值大小排序,支持升序和降序;
- sum:數組對象根據條件函數指定想的數組求和;
- toggle:查找數組中是否有我們給定的項,有則刪除,沒有則添加;
- unique:數組去重,去除數組中重覆的項;
- zipToObject:將第一個數組中的鍵映射到第二個數組中對應的值;
- zip:把兩個數組變為二維數組,二維數組中的每個數組包含兩個項分別為兩個傳入數組的相同位置的項。
寫在後面
- 後續作者會整理一份
radash
完整方法目錄上傳,方便沒法訪問外網的朋友查看使用。 - 下期方法分享完後,會同步整理分享Array方法的使用說明目錄,方便大家查閱對照使用。
- 小tips:不出意外的話博主每周五會定時更新,出意外的話就是出意外了。
- 大家有任何問題或見解,歡迎評論區留言交流和批評指正!!!
- 點擊訪問:radash官網