<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      lodash已死?radash庫方法介紹及源碼解析 —— 對象方法篇

      radash.jpg

      寫在前面

      • 主頁有更多其他篇章的方法,歡迎訪問查看。
      • 本篇我們介紹radash中對象相關方法的使用和源碼解析。

      assign:遞歸合并兩個對象

      1. 使用說明
        • 功能說明:類似于 JavaScript 的 Object.assign 方法,用于將 override 對象的屬性和值復制到 initial 對象中。如果屬性值是對象,則遞歸地進行賦值。
        • 參數:初始對象、覆蓋對象。
        • 返回值:返回合并后的新對象
      2. 使用代碼示例
        import { assign } from 'radash'
        
        const ra = {
          name: 'Ra',
          power: 100
        }
        
        assign(ra, { name: 'Loki' })
        // => { name: Loki, power: 100 }
        
      3. 源碼解析
        // 定義一個泛型函數 `assign`。
        export const assign = <X extends Record<string | symbol | number, any>>(
          // `initial` 是初始對象,它的屬性可能被 `override` 對象中的屬性覆蓋。
          initial: X,
          // `override` 是覆蓋對象,其屬性將覆蓋或添加到 `initial` 對象中。
          override: X
        ): X => {
          // 如果 `initial` 或 `override` 為空,則返回非空的那個,或者如果都為空則返回一個空對象。
          if (!initial || !override) return initial ?? override ?? {}
        
          // 使用 `Object.entries` 和 `reduce` 方法合并 `initial` 和 `override` 對象。
          return Object.entries({ ...initial, ...override }).reduce(
            (acc, [key, value]) => {
              // 在每次迭代中,構建累加器 `acc`,它是最終返回的新對象。
              return {
                ...acc,
                [key]: (() => {
                  // 如果 `initial` 中的對應屬性是一個對象,則遞歸地調用 `assign` 進行合并。
                  if (isObject(initial[key])) return assign(initial[key], value)
                  // 如果屬性值是數組,這里有一個注釋掉的代碼行,似乎是未完成的邏輯。
                  // if (isArray(value)) return value.map(x => assign)
                  // 對于非對象屬性,直接使用 `override` 中的值。
                  return value
                })()
              }
            },
            {} as X // 初始累加器是一個類型為 `X` 的空對象。
          )
        }
        
        • 方法流程說明:
          1. assign 函數接受兩個參數,initialoverride,它們都是對象。
          2. 如果其中一個對象為空,函數將返回另一個非空對象。如果兩個對象都為空,函數返回一個空對象。
          3. 如果兩個對象都非空,函數使用 Object.entriesreduce 方法遍歷 override 對象的所有屬性。
          4. 對于每個屬性,如果 initial 對象中對應的屬性也是一個對象,則遞歸地調用 assign 函數來合并這兩個對象。
          5. 如果 initial 對象中對應的屬性不是對象,或 override 對象中的屬性在 initial 對象中不存在,則直接使用 override 對象中的值。
          6. 返回合并后的新對象。

      clone:淺拷貝對象

      1. 使用說明
        • 功能說明:這個函數接受一個對象 obj 作為參數,并返回這個對象的一個新的淺拷貝。
        • 參數:需要克隆的對象。
        • 返回值:過濾完后的映射值組成的數組。
      2. 使用代碼示例
        import { clone } from 'radash'
        
        const ra = {
          name: 'Ra',
          power: 100
        }
        
        const gods = [ra]
        
        clone(ra) // => copy of ra
        clone(gods) // => copy of gods
        
      3. 源碼解析
        // 定義一個泛型函數 `clone`。
        export const clone = <T>(obj: T): T => {
          // 如果 `obj` 是原始值(如數字、字符串或布爾值),則不需要克隆,直接返回 `obj`。
          if (isPrimitive(obj)) {
            return obj
          }
        
          // 如果 `obj` 是一個函數,則通過 `bind` 方法創建一個新的綁定函數,
          // 并將其綁定到一個空對象上,以創建一個函數的副本。
          if (typeof obj === 'function') {
            return obj.bind({})
          }
        
          // 獲取 `obj` 的構造函數,并使用 `new` 操作符創建一個新的對象實例。
          // 這個方法同樣適用于創建數組的副本。
          const newObj = new ((obj as object).constructor as { new (): T })()
        
          // 遍歷 `obj` 的所有自有屬性,并將它們復制到新對象 `newObj` 中。
          Object.getOwnPropertyNames(obj).forEach(prop => {
            // 這里使用了類型斷言 `(newObj as any)` 和 `(obj as any)` 來繞過類型檢查,
            // 因為函數開頭已經檢查了原始值的情況。
            ;(newObj as any)[prop] = (obj as any)[prop]
          })
        
          // 返回新創建的對象 `newObj`。
          return newObj
        }
        
        • 方法流程說明:
          1. 如果 obj 是一個原始值,直接返回它,因為原始值在JavaScript中是不可變的。
          2. 如果 obj 是一個函數,使用 bind 方法創建并返回一個新的函數副本。
          3. 如果 obj 是一個對象或數組,使用 obj 的構造函數創建一個新的空對象或空數組 newObj。
          4. 遍歷 obj 的自有屬性,并將每個屬性值復制到 newObj 中。
          5. 返回新對象 newObj。

      construct:把扁平對象構建為深層對象(多維)

      1. 使用說明
        • 功能說明:這個函數接受一個對象 obj 作為參數,并返回這個對象的一個新的淺拷貝。
        • 參數:鍵值對對象。
        • 返回值:構建后的新對象。
      2. 使用代碼示例
        import { construct } from 'radash'
        
        const flat = {
          name: 'ra',
          power: 100,
          'friend.name': 'loki',
          'friend.power': 80,
          'enemies.0.name': 'hathor',
          'enemies.0.power': 12
        }
        
        construct(flat)
        // {
        //   name: 'ra',
        //   power: 100,
        //   friend: {
        //     name: 'loki',
        //     power: 80
        //   },
        //   enemies: [
        //     {
        //       name: 'hathor',
        //       power: 12
        //     }
        //   ]
        // }
        
      3. 源碼解析
        // 定義一個泛型函數 `construct`。
        export const construct = <TObject extends object>(obj: TObject): object => {
          // 如果 `obj` 為空,則直接返回一個新的空對象。
          if (!obj) return {}
        
          // 使用 `Object.keys` 獲取 `obj` 的所有自有屬性的鍵名,
          // 然后使用 `reduce` 方法來構建新對象。
          return Object.keys(obj).reduce((acc, path) => {
            // 對每個屬性鍵名 `path`,調用 `set` 函數來設置新對象 `acc` 的屬性。
            // `(obj as any)[path]` 獲取 `obj` 中對應屬性的值。
            // `set` 函數的具體實現未提供,我們可以假設它正確地設置了 `acc` 的屬性。
            return set(acc, path, (obj as any)[path])
          }, {}) // 初始累加器 `acc` 是一個空對象。
        }
        
        • 方法流程說明:
          1. construct 函數接受一個對象 obj 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 obj 非空,函數遍歷 obj 的所有自有屬性。
          4. 對于每個屬性,函數使用 set 函數將 obj 中的屬性值復制到新對象中。
          5. 返回構建完成的新對象。

      crush:把深層(多維)對象構建成扁平對象(construct的相反操作)

      1. 使用說明
        • 功能說明:這個函數接受一個對象 obj 作為參數,并返回這個對象的一個新的淺拷貝。
        • 參數:對象。
        • 返回值:構建后的扁平數組。
      2. 使用代碼示例
        import { crush } from 'radash'
        
        const ra = {
          name: 'ra',
          power: 100,
          friend: {
            name: 'loki',
            power: 80
          },
          enemies: [
            {
              name: 'hathor',
              power: 12
            }
          ]
        }
        
        crush(ra)
        // {
        //   name: 'ra',
        //   power: 100,
        //   'friend.name': 'loki',
        //   'friend.power': 80,
        //   'enemies.0.name': 'hathor',
        //   'enemies.0.power': 12
        // }
        
      3. 源碼解析
        // 定義一個泛型函數 `crush`。
        export const crush = <TValue extends object>(value: TValue): object => {
          // 如果 `value` 為空,則直接返回一個空對象。
          if (!value) return {}
        
          // 使用 `objectify` 函數來構建新對象。
          // `objectify` 函數的具體實現未提供,我們可以假設它以某種方式構建對象。
          return objectify(
            // 使用 `keys` 函數獲取 `value` 的所有鍵名。
            // `keys` 函數的具體實現未提供,我們可以假設它返回對象的所有鍵名。
            keys(value),
            // 使用標識函數 `k => k` 作為鍵生成函數,意味著新對象的鍵將與原始對象的鍵相同。
            k => k,
            // 使用 `get` 函數獲取 `value` 對象中每個鍵對應的值。
            // `get` 函數的具體實現未提供,我們可以假設它正確地獲取了對象中的屬性值。
            k => get(value, k)
          )
        }
        
        • 方法流程說明:
          1. crush 函數接受一個對象 value 作為參數。
          2. 如果 value 為空,函數返回一個空對象。
          3. 如果 value 非空,函數使用 keys 函數獲取 value 的所有鍵名。
          4. 函數調用 objectify,傳入鍵名數組、鍵生成函數(這里是標識函數 k => k)和值生成函數(通過調用 get(value, k) 獲取每個鍵的值)。
          5. objectify 函數返回一個新對象,這個對象的屬性和值與 value 相同。

      get:獲取對象中的任意屬性,可以通過 . 的方式獲取深層的屬性

      1. 使用說明
        • 功能說明:用于安全地訪問嵌套對象的屬性,即使某些中間屬性不存在也不會拋出錯誤。如果找不到指定的路徑,則返回一個默認值。
        • 參數:目標對象、屬性字符(可以.表示深層次屬性)、默認值。
        • 返回值:找到則返回指定值,否則返回默認值。
      2. 使用代碼示例
        import { get } from 'radash'
        
        const fish = {
          name: 'Bass',
          weight: 8,
          sizes: [
            {
              maturity: 'adult',
              range: [7, 18],
              unit: 'inches'
            }
          ]
        }
        
        get( fish, 'sizes[0].range[1]' ) // 18
        get( fish, 'sizes.0.range.1' ) // 18
        get( fish, 'foo', 'default' ) // 'default'
        
      3. 源碼解析
        // 定義一個泛型函數 `get`。
        export const get = <TDefault = unknown>(
          // 第一個參數 `value` 是一個任意類型的值,它是要訪問屬性的對象。
          value: any,
          // 第二個參數 `path` 是一個字符串,表示對象屬性的路徑,使用點或方括號表示法。
          path: string,
          // 第三個可選參數 `defaultValue` 是一個默認值,如果無法訪問路徑,則返回此值。
          defaultValue?: TDefault
        ): TDefault => {
          // 使用正則表達式分割路徑字符串,得到一個屬性名的數組 `segments`。
          const segments = path.split(/[.[]]/g)
          // 初始化一個變量 `current`,用于遍歷屬性路徑。
          let current: any = value
          // 遍歷 `segments` 中的每個屬性名 `key`。
          for (const key of segments) {
            // 如果 `current` 是 `null` 或 `undefined`,則返回 `defaultValue`。
            if (current === null || current === undefined) return defaultValue as TDefault
            // 移除屬性名中的引號。
            const dequoted = key.replace(/['"]/g, '')
            // 如果屬性名為空(可能是由于路徑字符串中的多余點或方括號),則跳過此迭代。
            if (dequoted.trim() === '') continue
            // 將 `current` 更新為當前屬性名 `dequoted` 對應的值。
            current = current[dequoted]
          }
          // 如果最終的 `current` 是 `undefined`,則返回 `defaultValue`。
          if (current === undefined) return defaultValue as TDefault
          // 否則,返回找到的值。
          return current
        }
        
        • 方法流程說明:
          1. get 函數接受一個對象 value,一個表示屬性路徑的字符串 path,以及一個可選的默認值 defaultValue。
          2. 使用正則表達式分割 path 字符串,得到一個表示屬性鏈的數組 segments
          3. 遍歷 segments 數組,依次訪問每個屬性。
          4. 如果在訪問過程中遇到 nullundefined,或者到達路徑的末尾但找不到值,則返回 defaultValue
          5. 如果成功訪問到路徑上的所有屬性,并找到了值,則返回這個值。

      invert:把對象中的keyvalue對調

      1. 使用說明
        • 功能說明:用于反轉對象的鍵和值。這意味著原始對象的鍵成為新對象的值,原始對象的值成為新對象的鍵。
        • 參數:需要反轉的對象。
        • 返回值:反轉后的新數組。
      2. 使用代碼示例
        import { invert } from 'radash'
        
        const powersByGod = {
          ra: 'sun',
          loki: 'tricks',
          zeus: 'lighning'
        }
        
        invert(gods) // => { sun: ra, tricks: loki, lightning: zeus }
        
      3. 源碼解析
        // 定義一個泛型函數 `invert`。
        export const invert = <
          // 泛型 `TKey` 表示對象的鍵的類型。
          TKey extends string | number | symbol,
          // 泛型 `TValue` 表示對象的值的類型。
          TValue extends string | number | symbol
        >(
          // 參數 `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>
        ): Record<TValue, TKey> => {
          // 如果 `obj` 為空,則返回一個空對象。
          if (!obj) return {} as Record<TValue, TKey>
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并斷言鍵的類型為 `TKey`。
          const keys = Object.keys(obj) as TKey[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象,其鍵為 `obj` 的值,值為 `obj` 的鍵。
          return keys.reduce((acc, key) => {
            // 將 `obj` 的值 `obj[key]` 作為新對象 `acc` 的鍵,原始鍵 `key` 作為新對象的值。
            acc[obj[key]] = key
            // 返回累加器 `acc`,它是正在構建的反轉對象。
            return acc
          }, {} as Record<TValue, TKey>) // 初始累加器是一個空對象,類型為 `Record<TValue, TKey>`。
        }
        
        • 方法流程說明:
          1. invert 函數接受一個對象 obj 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 obj 非空,函數遍歷 obj 的所有鍵。
          4. 對于每個鍵,函數將 obj 中的值作為新對象的鍵,將原始鍵作為新對象的值。
          5. 返回構建完成的新對象,它是 obj 的反轉版本。

      keys:獲取對象中所有的key,包括深層的(表示成a.b的形式)

      1. 使用說明
        • 功能說明:于獲取一個對象的所有嵌套屬性鍵的完整路徑。這些路徑用點號連接,表示從根到葉子的完整路徑。
        • 參數:目標對象。
        • 返回值:過濾完后的映射值組成的數組。
      2. 使用代碼示例
        import { keys } from 'radash'
        
        const ra = {
          name: 'ra',
          power: 100,
          friend: {
            name: 'loki',
            power: 80
          },
          enemies: [
            {
              name: 'hathor',
              power: 12
            }
          ]
        }
        
        keys(ra)
        // => [
        //   'name',
        //   'power',
        //   'friend.name',
        //   'friend.power',
        //   'enemies.0.name',
        //   'enemies.0.power'
        // ]
        
      3. 源碼解析
        // 定義一個泛型函數 `keys`。
        export const keys = <TValue extends object>(value: TValue): string[] => {
          // 如果 `value` 為空,則返回一個空數組。
          if (!value) return []
        
          // 定義一個遞歸函數 `getKeys`,用于遍歷嵌套對象或數組并獲取所有鍵的路徑。
          const getKeys = (nested: any, paths: string[]): string[] => {
            // 如果當前值 `nested` 是一個對象,遞歸地遍歷它的每一個鍵值對。
            if (isObject(nested)) {
              return Object.entries(nested).flatMap(([k, v]) =>
                // 對于每一個鍵值對,將鍵 `k` 添加到路徑數組 `paths` 中,
                // 并繼續遞歸地遍歷值 `v`。
                getKeys(v, [...paths, k])
              )
            }
            // 如果當前值 `nested` 是一個數組,遞歸地遍歷它的每一個元素。
            if (isArray(nested)) {
              return nested.flatMap((item, i) => 
                // 對于每一個元素,將索引 `i` 轉換為字符串并添加到路徑數組 `paths` 中,
                // 然后繼續遞歸地遍歷元素 `item`。
                getKeys(item, [...paths, `${i}`])
              )
            }
            // 如果當前值 `nested` 既不是對象也不是數組,說明已經到達葉子節點,
            // 將路徑數組 `paths` 連接成字符串并返回。
            return [paths.join('.')]
          }
          // 使用 `getKeys` 函數從根開始遍歷 `value`,并獲取所有鍵的路徑。
          return getKeys(value, [])
        }
        
        • 方法流程說明:
          1. keys 函數接受一個對象 value 作為參數。
          2. 如果 value 為空,函數返回一個空數組。
          3. 如果 value 非空,函數定義了一個遞歸輔助函數 getKeys
          4. getKeys 函數遞歸地遍歷嵌套對象或數組,收集所有鍵的路徑。
          5. 對于嵌套對象,getKeys 遍歷每個鍵值對,并對值遞歸調用自身。
          6. 對于嵌套數組,getKeys 遍歷每個元素,并對元素遞歸調用自身,使用元素索引作為路徑的一部分。
          7. 當到達葉子節點(即不再是對象或數組)時,getKeys 將收集到的路徑數組 paths 連接成字符串并返回。
          8. keys 函數返回一個包含所有屬性鍵路徑的數組。

      listify:把對象的鍵值對轉換成一個由特定結構元素組成的數組

      1. 使用說明
        • 功能說明:用于將一個對象的鍵值對轉換成一個由特定結構元素組成的數組。這個函數接受兩個參數:一個對象 obj 和一個轉換函數 toItem。toItem 函數接受對象的每個鍵和對應的值,并返回一個新的元素。
        • 參數:目標對象、條件函數。
        • 返回值:構建后的結果數組。
      2. 使用代碼示例
        import { listify } from 'radash'
        
        const fish = {
          marlin: {
            weight: 105,
          },
          bass: {
            weight: 8,
          }
        }
        
        listify(fish, (key, value) => ({ ...value, name: key })) // => [{ name: 'marlin', weight: 105 }, { name: 'bass', weight: 8 }]
        
      3. 源碼解析
        // 定義一個泛型函數 `listify`。
        export const listify = <TValue, TKey extends string | number | symbol, KResult>(
          // 參數 `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // 參數 `toItem` 是一個函數,它接受一個鍵和一個值,并返回一個新的結果類型 `KResult` 的元素。
          toItem: (key: TKey, value: TValue) => KResult
        ) => {
          // 如果 `obj` 為空,則返回一個空數組。
          if (!obj) return []
          // 使用 `Object.entries` 獲取 `obj` 的所有鍵值對。
          const entries = Object.entries(obj)
          // 如果 `obj` 沒有鍵值對,返回一個空數組。
          if (entries.length === 0) return []
          // 使用 `reduce` 方法遍歷所有鍵值對,構建結果數組。
          return entries.reduce((acc, entry) => {
            // 對每個鍵值對,調用 `toItem` 函數,并將返回的元素添加到累加器數組 `acc` 中。
            acc.push(toItem(entry[0] as TKey, entry[1] as TValue))
            // 返回累加器 `acc`。
            return acc
          }, [] as KResult[]) // 初始累加器是一個空數組,其元素類型為 `KResult`。
        }
        
        • 方法流程說明:
          1. listify 函數接受一個對象 obj 和一個轉換函數 toItem 作為參數。
          2. 如果 obj 為空,函數返回一個空數組。
          3. 如果 obj 非空,函數使用 Object.entries 獲取 obj 的所有鍵值對。
          4. 如果 obj 沒有鍵值對,函數返回一個空數組。
          5. 如果 obj 有鍵值對,函數使用 reduce 方法遍歷鍵值對數組。
          6. 對于每個鍵值對,函數調用 toItem 函數,傳入鍵和值,并將返回的新元素添加到累加器數組中。
          7. 返回構建完成的結果數組。

      lowerize:將對象的所有key轉換為小寫形式

      1. 使用說明
        • 功能說明:用于將一個對象的所有鍵轉換為小寫形式,內部用到mapKeys,而 mapKeys 函數則用于一般性地將一個對象的鍵通過一個映射函數轉換為新的鍵。
        • 參數:對象、映射函數。
        • 返回值:返回一個鍵是小寫形式的對象。
      2. 使用代碼示例
        import { lowerize } from 'radash'
        
        const ra = {
          Mode: 'god',
          Power: 'sun'
        }
        
        lowerize(ra) // => { mode, power }
        
      3. 源碼解析
        // 定義一個泛型函數 `lowerize`。
        export const lowerize = <T extends Record<string, any>>(obj: T) =>
          // 調用 `mapKeys` 函數將 `obj` 的所有鍵轉換為小寫。
          mapKeys(obj, k => k.toLowerCase()) as LowercasedKeys<T>
          // `LowercasedKeys<T>` 是一個類型,表示將 `T` 的鍵轉換為小寫后的新類型。
        
        // 定義一個泛型函數 `mapKeys`。
        export const mapKeys = <
          // `TValue` 表示對象的值的類型。
          TValue,
          // `TKey` 表示對象原始鍵的類型。
          TKey extends string | number | symbol,
          // `TNewKey` 表示映射后的新鍵的類型。
          TNewKey extends string | number | symbol
        >(
          // `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // `mapFunc` 是一個映射函數,它接受一個鍵和一個值,并返回一個新的鍵。
          mapFunc: (key: TKey, value: TValue) => TNewKey
        ): Record<TNewKey, TValue> => {
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并斷言鍵的類型為 `TKey`。
          const keys = Object.keys(obj) as TKey[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象,其鍵為 `mapFunc` 函數的返回值,值為 `obj` 的值。
          return keys.reduce((acc, key) => {
            // 調用 `mapFunc` 函數獲取新鍵,并將 `obj` 中的值賦給新鍵。
            acc[mapFunc(key as TKey, obj[key])] = obj[key]
            // 返回累加器 `acc`,它是正在構建的新對象。
            return acc
          }, {} as Record<TNewKey, TValue>) // 初始累加器是一個空對象,類型為 `Record<TNewKey, TValue>`。
        }
        
        • 方法流程說明:
          1. lowerize 函數接受一個對象 obj 作為參數。
          2. 它調用 mapKeys 函數,傳入 obj 和一個將鍵轉換為小寫的函數。
          3. mapKeys 函數遍歷 obj 的所有鍵,并將每個鍵轉換為小寫。
          4. mapKeys 返回一個新對象,這個對象的鍵是小寫形式,值與原始對象 obj 相同。
          5. lowerize 函數返回這個新對象,并使用 LowercasedKeys<T> 類型斷言來指明返回值的類型。

      upperize:將對象的所有key轉換為大寫形式

      1. 使用說明
        • 功能說明:用于將一個對象的所有鍵轉換為大寫形式,而 mapKeys 函數則用于一般性地將一個對象的鍵通過一個映射函數 mapFunc 轉換為新的鍵。
        • 參數:目標對象、映射函數。
        • 返回值:轉換后的新對象。
      2. 使用代碼示例
        import { upperize } from 'radash'
        
        const ra = {
          Mode: 'god',
          Power: 'sun'
        }
        
        upperize(ra) // => { MODE, POWER }
        
      3. 源碼解析
        // 定義一個泛型函數 `upperize`。
        export const upperize = <T extends Record<string, any>>(obj: T) =>
          // 調用 `mapKeys` 函數將 `obj` 的所有鍵轉換為大寫。
          mapKeys(obj, k => k.toUpperCase()) as UppercasedKeys<T>
          // `UppercasedKeys<T>` 是一個類型,表示將 `T` 的鍵轉換為大寫后的新類型。
        
        // 定義一個泛型函數 `mapKeys`。
        export const mapKeys = <
          // `TValue` 表示對象的值的類型。
          TValue,
          // `TKey` 表示原始對象的鍵的類型。
          TKey extends string | number | symbol,
          // `TNewKey` 表示映射后的新鍵的類型。
          TNewKey extends string | number | symbol
        >(
          // `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // `mapFunc` 是一個映射函數,它接受一個鍵和一個值,并返回一個新的鍵。
          mapFunc: (key: TKey, value: TValue) => TNewKey
        ): Record<TNewKey, TValue> => {
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并斷言它們的類型為 `TKey`。
          const keys = Object.keys(obj) as TKey[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象,其鍵為 `mapFunc` 函數的返回值,值為 `obj` 的值。
          return keys.reduce((acc, key) => {
            // 調用 `mapFunc` 函數獲取新鍵,并將 `obj` 中的值賦給新鍵。
            acc[mapFunc(key as TKey, obj[key])] = obj[key]
            // 返回累加器 `acc`,它是正在構建的新對象。
            return acc
          }, {} as Record<TNewKey, TValue>) // 初始累加器是一個空對象,類型為 `Record<TNewKey, TValue>`。
        }
        
        • 方法流程說明:
          1. upperize 函數接受一個對象 obj 作為參數。
          2. 它調用 mapKeys 函數,傳入 obj 和一個將鍵轉換為大寫的函數。
          3. mapKeys 函數遍歷 obj 的所有鍵,并將每個鍵轉換為大寫。
          4. mapKeys 返回一個新對象,這個對象的鍵是大寫形式,值與原始對象 obj 相同。
          5. upperize 函數返回這個新對象,并使用 UppercasedKeys<T> 類型斷言來指明返回值的類型。

      mapEntries:將對象的鍵值對通過一個轉換函數映射為新的對象

      1. 使用說明
        • 功能說明:用于將一個對象的鍵值對通過一個轉換函數 toEntry 映射為新的鍵值對,并創建一個新的對象。這個函數接受兩個參數:一個對象 obj 和一個轉換函數 toEntrytoEntry 函數接受對象的每個鍵和對應的值,并返回一個包含新鍵和新值的元組。
        • 參數:目標對象、轉換函數。
        • 返回值:構建完成的結果對象。
      2. 使用代碼示例
        import { mapEntries } from 'radash'
        
        const ra = {
          name: 'Ra',
          power: 'sun',
          rank: 100,
          culture: 'egypt'
        }
        
        mapEntries(ra, (key, value) => [key.toUpperCase(), `${value}`]) // => { NAME: 'Ra', POWER: 'sun', RANK: '100', CULTURE: 'egypt' }
        
      3. 源碼解析
        // 定義一個泛型函數 `mapEntries`。
        export const mapEntries = <
          // `TKey` 表示原始對象的鍵的類型。
          TKey extends string | number | symbol,
          // `TValue` 表示原始對象的值的類型。
          TValue,
          // `TNewKey` 表示新對象的鍵的類型。
          TNewKey extends string | number | symbol,
          // `TNewValue` 表示新對象的值的類型。
          TNewValue
        >(
          // `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // `toEntry` 是一個轉換函數,它接受一個鍵和一個值,并返回一個新的鍵值對的元組。
          toEntry: (key: TKey, value: TValue) => [TNewKey, TNewValue]
        ): Record<TNewKey, TNewValue> => {
          // 如果 `obj` 為空,則返回一個空對象。
          if (!obj) return {} as Record<TNewKey, TNewValue>
        
          // 使用 `Object.entries` 獲取 `obj` 的所有鍵值對,并使用 `reduce` 方法來構建新對象。
          return Object.entries(obj).reduce((acc, [key, value]) => {
            // 對每個鍵值對,調用 `toEntry` 函數,并獲取新鍵 `newKey` 和新值 `newValue`。
            const [newKey, newValue] = toEntry(key as TKey, value as TValue)
            // 將新鍵值對添加到累加器對象 `acc` 中。
            acc[newKey] = newValue
            // 返回累加器 `acc`。
            return acc
          }, {} as Record<TNewKey, TNewValue>) // 初始累加器是一個空對象,類型為 `Record<TNewKey, TNewValue>`。
        }
        
        • 方法流程說明:
          1. mapEntries 函數接受一個對象 obj 和一個轉換函數 toEntry 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 obj 非空,函數使用 Object.entries 獲取 obj 的所有鍵值對。
          4. 函數使用 reduce 方法遍歷鍵值對數組。
          5. 對于每個鍵值對,函數調用 toEntry 函數,傳入鍵和值,并將返回的新鍵值對添加到累加器數組中。
          6. 返回構建完成的結果對象。

      mapKeys:把對象的kye通過一個映射函數轉換為新的key

      1. 使用說明
        • 功能說明:將一個對象的鍵通過一個映射函數 mapFunc 轉換為新的鍵,并創建一個新對象。這個函數接受兩個參數:一個對象 obj 和一個映射函數 mapFunc。mapFunc 函數接受對象的每個鍵和對應的值,并返回一個新的鍵。
        • 參數:目標對象、映射函數。
        • 返回值:構建完成的新對象。
      2. 使用代碼示例
        import { mapKeys } from 'radash'
        
        const ra = {
          mode: 'god',
          power: 'sun'
        }
        
        mapKeys(ra, key => key.toUpperCase()) // => { MODE, POWER }
        mapKeys(ra, (key, value) => value) // => { god: 'god', power: 'power' }
        
      3. 源碼解析
        // 定義一個泛型函數 `mapKeys`。
        export const mapKeys = <
          // `TValue` 表示對象的值的類型。
          TValue,
          // `TKey` 表示原始對象的鍵的類型。
          TKey extends string | number | symbol,
          // `TNewKey` 表示映射后的新鍵的類型。
          TNewKey extends string | number | symbol
        >(
          // `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // `mapFunc` 是一個映射函數,它接受一個鍵和一個值,并返回一個新的鍵。
          mapFunc: (key: TKey, value: TValue) => TNewKey
        ): Record<TNewKey, TValue> => {
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并斷言它們的類型為 `TKey`。
          const keys = Object.keys(obj) as TKey[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象,其鍵為 `mapFunc` 函數的返回值,值為 `obj` 的值。
          return keys.reduce((acc, key) => {
            // 調用 `mapFunc` 函數獲取新鍵,并將 `obj` 中的值賦給新鍵。
            acc[mapFunc(key as TKey, obj[key])] = obj[key]
            // 返回累加器 `acc`,它是正在構建的新對象。
            return acc
          }, {} as Record<TNewKey, TValue>) // 初始累加器是一個空對象,類型為 `Record<TNewKey, TValue>`。
        }
        
        • 方法流程說明:
          1. mapKeys 函數接受一個對象 obj 和一個映射函數 mapFunc 作為參數。
          2. 函數使用 Object.keys 獲取 obj 的所有鍵。
          3. 函數使用 reduce 方法遍歷鍵數組。
          4. 對于每個鍵,函數調用 mapFunc 函數,傳入鍵和值,并將返回的新鍵作為新對象的鍵。
          5. 新對象的值與原始對象 obj 中的值相同。
          6. 返回構建完成的新對象。

      mapValues:對象的value通過一個映射函數轉換為新的value

      1. 使用說明
        • 功能說明:將一個對象的值通過一個映射函數 mapFunc 轉換為新的值,并創建一個新對象。這個函數接受兩個參數:一個對象 obj 和一個映射函數 mapFuncmapFunc 函數接受對象的每個值和對應的鍵,并返回一個新的值。
        • 參數:目標對象、映射函數。
        • 返回值:構建完成的新對象。
      2. 使用代碼示例
        import { clone } from 'radash'
        
        const ra = {
          name: 'Ra',
          power: 100
        }
        
        const gods = [ra]
        
        clone(ra) // => copy of ra
        clone(gods) // => copy of gods
        
      3. 源碼解析
        // 定義一個泛型函數 `mapValues`。
        export const mapValues = <
          // `TValue` 表示原始對象的值的類型。
          TValue,
          // `TKey` 表示對象鍵的類型。
          TKey extends string | number | symbol,
          // `TNewValue` 表示映射后的新值的類型。
          TNewValue
        >(
          // `obj` 是一個對象,其鍵的類型為 `TKey`,值的類型為 `TValue`。
          obj: Record<TKey, TValue>,
          // `mapFunc` 是一個映射函數,它接受一個值和一個鍵,并返回一個新的值。
          mapFunc: (value: TValue, key: TKey) => TNewValue
        ): Record<TKey, TNewValue> => {
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并斷言它們的類型為 `TKey`。
          const keys = Object.keys(obj) as TKey[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象,其鍵與 `obj` 相同,值為 `mapFunc` 函數的返回值。
          return keys.reduce((acc, key) => {
            // 調用 `mapFunc` 函數獲取新值,并將其賦給新對象 `acc` 的同名鍵。
            acc[key] = mapFunc(obj[key], key)
            // 返回累加器 `acc`,它是正在構建的新對象。
            return acc
          }, {} as Record<TKey, TNewValue>) // 初始累加器是一個空對象,類型為 `Record<TKey, TNewValue>`。
        }
        
        • 方法流程說明:
          1. mapValues 函數接受一個對象 obj 和一個映射函數 mapFunc 作為參數。
          2. 函數使用 Object.keys 獲取 obj 的所有鍵。
          3. 函數使用 reduce 方法遍歷鍵數組。
          4. 對于每個鍵,函數調用 mapFunc 函數,傳入值和鍵,并將返回的新值作為新對象的值。
          5. 新對象的鍵與原始對象 obj 中的鍵相同。
          6. 返回構建完成的新對象。

      omit:創建一個省略了 keys 數組中指定的一些鍵的新對象

      1. 使用說明
        • 功能說明:創建一個新的對象,該對象是原始對象 obj 的副本,但省略了 keys 數組中指定的一些鍵。這個函數接受兩個參數:一個對象 obj 和一個包含要省略鍵名的數組 keys
        • 參數:目標對象、要省略的key數組。
        • 返回值:省略了指定鍵的新對象。
      2. 使用代碼示例
        import { omit } from 'radash'
        
        const fish = {
          name: 'Bass',
          weight: 8,
          source: 'lake',
          brackish: false
        }
        
        omit(fish, ['name', 'source']) // => { weight, brackish }
        
      3. 源碼解析
        // 定義一個泛型函數 `omit`。
        export const omit = <T, TKeys extends keyof T>(
          // `obj` 是一個對象,其類型為泛型 `T`。
          obj: T,
          // `keys` 是一個數組,包含對象 `obj` 中要省略的鍵名,鍵名的類型為 `TKeys`。
          keys: TKeys[]
        ): Omit<T, TKeys> => {
          // 如果 `obj` 為空,則返回一個空對象。
          if (!obj) return {} as Omit<T, TKeys>
          // 如果 `keys` 為空或長度為0,則返回原始對象 `obj`。
          if (!keys || keys.length === 0) return obj as Omit<T, TKeys>
          // 使用 `reduce` 方法遍歷 `keys` 數組,從 `obj` 中省略指定的鍵。
          return keys.reduce(
            (acc, key) => {
              // 在這個較為局限的上下文中,允許直接在累加器對象 `acc` 上使用 `delete` 操作符。
              // 這是出于性能考慮,通常不建議在其他地方使用這種模式。
              delete acc[key]
              // 返回更新后的累加器 `acc`。
              return acc
            },
            // 使用對象展開運算符 `{ ...obj }` 創建 `obj` 的淺拷貝,以避免直接修改原始對象。
            { ...obj }
          )
        }
        
        • 方法流程說明:
          1. omit 函數接受一個對象 obj 和一個鍵名數組 keys 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 keys 為空或長度為0,函數返回原始對象 obj。
          4. 如果 keys 非空,函數使用 reduce 方法遍歷 keys 數組。
          5. 對于每個鍵名 key,函數使用 delete 操作符將其從累加器對象 acc 中刪除。
          6. 函數返回省略了指定鍵的新對象。

      pick:創建一個只包含原始對象中指定的 keys`的對象

      1. 使用說明
        • 功能說明:創建一個新的對象,該對象只包含原始對象 obj 中指定的 keys。這個函數接受兩個參數:一個對象 obj 和一個包含要選擇鍵名的數組 keys
        • 參數:目標對象、需要包含的key的數組
        • 返回值:過濾完后的映射值組成的數組。
      2. 使用代碼示例
        import { pick } from 'radash'
        
        const fish = {
          name: 'Bass',
          weight: 8,
          source: 'lake',
          barckish: false
        }
        
        pick(fish, ['name', 'source']) // => { name, source }
        
      3. 源碼解析
        // 定義一個泛型函數 `pick`。
        export const pick = <T extends object, TKeys extends keyof T>(
          // `obj` 是一個對象,其類型為泛型 `T`。
          obj: T,
          // `keys` 是一個數組,包含對象 `obj` 中要選擇的鍵名,鍵名的類型為 `TKeys`。
          keys: TKeys[]
        ): Pick<T, TKeys> => {
          // 如果 `obj` 為空,則返回一個空對象。
          if (!obj) return {} as Pick<T, TKeys>
          // 使用 `reduce` 方法遍歷 `keys` 數組,從 `obj` 中選擇指定的鍵。
          return keys.reduce((acc, key) => {
            // 檢查 `obj` 是否自身擁有屬性 `key`(不是從原型鏈繼承來的)。
            if (Object.prototype.hasOwnProperty.call(obj, key)) 
              // 如果 `obj` 擁有 `key`,則將其添加到累加器對象 `acc` 中。
              acc[key] = obj[key]
            // 返回累加器 `acc`。
            return acc
          }, {} as Pick<T, TKeys>) // 初始累加器是一個空對象,類型為 `Pick<T, TKeys>`。
        }
        
        • 方法流程說明:
          1. pick 函數接受一個對象 obj 和一個鍵名數組 keys 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 obj 非空,函數使用 reduce 方法遍歷 keys 數組。
          4. 對于每個鍵名 key,函數檢查 obj 是否自身擁有這個屬性(而不是從原型鏈繼承的)。
          5. 如果 obj 自身擁有這個屬性,函數將這個屬性及其值添加到累加器對象 acc 中。
          6. 函數返回包含所選鍵的新對象。

      set:在一個對象中設置一個由點或方括號表示法指定的路徑上的值

      1. 使用說明
        • 功能說明:用于在一個對象中設置一個值,該值位于由點或方括號表示法指定的路徑上。如果路徑中的任何中間對象不存在,set 函數將創建它們。
        • 參數:初始對象、屬性路徑字符串、設置值。
      2. 使用代碼示例
        import { set } from 'radash'
        
        set({}, 'name', 'ra')
        // => { name: 'ra' }
        
        set({}, 'cards[0].value', 2)
        // => { cards: [{ value: 2 }] }
        
      3. 源碼解析
        // 定義一個泛型函數 `set`。
        export const set = <T extends object, K>(
          // `initial` 是初始對象,我們將在其中設置值。
          initial: T,
          // `path` 是一個字符串,表示要設置值的屬性路徑。
          path: string,
          // `value` 是我們要設置在路徑上的值。
          value: K
        ): T => {
          // 如果 `initial` 為空,則返回一個空對象。
          if (!initial) return {} as T
          // 如果 `path` 為空或 `value` 未定義,則返回原始對象 `initial`。
          if (!path || value === undefined) return initial
          // 使用正則表達式分割路徑字符串,得到一個屬性名的數組 `segments`。
          // 過濾掉空字符串,確保所有段都是有效的。
          const segments = path.split(/[.[]]/g).filter(x => !!x.trim())
        
          // 定義一個遞歸輔助函數 `_set`。
          const _set = (node: any) => {
            // 如果路徑 `segments` 有多個段,我們需要深入嵌套結構。
            if (segments.length > 1) {
              // 彈出當前段的鍵名 `key`。
              const key = segments.shift() as string
              // 檢查下一個段是否表示數組索引。
              const nextIsNum = toInt(segments[0], null) === null ? false : true
              // 如果當前鍵不存在,創建一個新的對象或數組,取決于下一個段是否是數字。
              node[key] = node[key] === undefined ? (nextIsNum ? [] : {}) : node[key]
              // 遞歸調用 `_set` 函數,繼續設置值。
              _set(node[key])
            } else {
              // 如果路徑 `segments` 只有一個段,直接在當前節點上設置值。
              node[segments[0]] = value
            }
          }
          // ...(函數的其余部分)
        }
        
        • 方法流程說明:
          1. set 函數接受一個對象 initial,一個路徑字符串 path,和一個值 value 作為參數。
          2. 如果 initial 為空,函數返回一個空對象。
          3. 如果 path 為空或 value 未定義,函數返回原始對象 initial
          4. 函數使用正則表達式分割 path 字符串,得到一個表示屬性鏈的數組 segments。
          5. 函數定義了一個遞歸輔助函數 _set,它負責沿著 segments 的路徑設置值。
          6. 如果 segments 數組有多個元素,函數遞歸地創建或獲取中間對象,并繼續沿著路徑設置值。
          7. 如果 segments 數組只有一個元素,函數在當前的節點上設置值。
          8. _set 函數從根對象 initial 開始遞歸設置值。

      shake:過濾對象

      1. 使用說明
        • 功能說明:創建一個新的對象,該對象是原始對象 obj 的副本,但省略了那些經過 filter 函數檢查并返回 true 的屬性。filter 函數默認會過濾掉值為 undefined 的屬性。
        • 參數:目標對象、[過濾函數]。
        • 返回值:過濾完后的映射值組成的數組。
      2. 使用代碼示例
        import { shake } from 'radash'
        
        const ra = {
          mode: 'god',
          greek: false,
          limit: undefined
        }
        
        shake(ra) // => { mode, greek }
        shake(ra, a => !a) // => { mode }
        
      3. 源碼解析
        // 定義一個泛型函數 `shake`。
        export const shake = <RemovedKeys extends string, T>(
          // 參數 `obj` 是一個對象,其類型為泛型 `T`。
          obj: T,
          // 參數 `filter` 是一個可選的函數,用于決定哪些屬性應該被省略。
          // 默認情況下,它會過濾掉值為 `undefined` 的屬性。
          filter: (value: any) => boolean = x => x === undefined
        ): Omit<T, RemovedKeys> => {
          // 如果 `obj` 為空,則返回一個空對象。
          // 這里返回的類型應該是 `Omit<T, RemovedKeys>` 而不是 `T`。
          if (!obj) return {} as Omit<T, RemovedKeys>
          // 使用 `Object.keys` 獲取 `obj` 的所有鍵,并將其類型斷言為 `T` 的鍵的類型數組。
          const keys = Object.keys(obj) as (keyof T)[]
          // 使用 `reduce` 方法遍歷所有鍵,創建一個新對象。
          return keys.reduce((acc, key) => {
            // 如果 `filter` 函數對當前鍵的值返回 `true`,則省略該屬性。
            if (filter(obj[key])) {
              return acc
            } else {
              // 否則,將屬性添加到累加器對象 `acc` 中。
              acc[key] = obj[key]
              return acc
            }
          }, {} as Omit<T, RemovedKeys>) // 初始累加器是一個空對象,類型為 `Omit<T, RemovedKeys>`。
        }
        
        • 方法流程說明:
          1. shake 函數接受一個對象 obj 和一個可選的過濾函數 filter 作為參數。
          2. 如果 obj 為空,函數返回一個空對象。
          3. 如果 obj 非空,函數使用 Object.keys 獲取 obj 的所有鍵。
          4. 函數使用 reduce 方法遍歷鍵數組。
          5. 對于每個鍵,函數使用 filter 函數檢查對應的值,以確定是否應該省略該屬性。
          6. 如果 filter 函數返回 false,函數將該屬性及其值添加到累加器對象 acc 中。
          7. 返回包含所選屬性的新對象。

      寫在后面

      • 我相信能看到最后的都是帥氣多金想進步的大漂亮和大帥筆,感謝閱讀到這兒!
      • 等所有方法更新完畢,作者會整理一份radash完整方法目錄上傳,包括思維導圖和使用目錄。
      • 大家有任何問題或見解,歡迎評論區留言交流和批評指正!??!
      • 你的每一個收藏都是作者寫作的動力?。。?/li>
      • 點擊訪問:radash官網
      posted @ 2024-05-24 16:58  山里看瓜  閱讀(398)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 国产国语一级毛片| 国产日韩AV免费无码一区二区三区 | 18岁日韩内射颜射午夜久久成人| 亚洲精品一区二区麻豆| 日韩无专区精品中文字幕| 国厂精品114福利电影免费| 越南女子杂交内射bbwxz| 国产精品久久久一区二区三区| 国产AV影片麻豆精品传媒| 国产亚洲精品VA片在线播放| 蜜桃av色偷偷av老熟女| 国产福利酱国产一区二区| 99久久国产综合精品色| 国产成人综合色视频精品| 国产午夜福利视频在线| 欧美激情精品久久| 国产成人精品视频国产| 午夜福利看片在线观看| 插入中文字幕在线一区二区三区| 97精品尹人久久大香线蕉| 亚洲av色图一区二区三区| 女人与公狍交酡女免费| 国产伦码精品一区二区| 亚洲一区二区三区蜜桃臀| 大伊香蕉精品一区二区| 化州市| 久久国内精品自在自线91| 国产不卡av一区二区| 粗了大了 整进去好爽视频| 日韩无矿砖一线二线卡乱| 亚洲高清日韩专区精品| 青草内射中出高潮| 国产精品三级黄色小视频| 18禁国产一区二区三区| 国产a在视频线精品视频下载| 国产精品成| 欧美牲交a欧美牲交aⅴ免费真| 国产中文三级全黄| 97久久综合亚洲色hezyo| 国产亚洲色婷婷久久99精品| 亚洲色偷偷偷网站色偷一区 |