国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

JavaScript 實(shí)現(xiàn)數(shù)組更多的高階函數(shù)

aervon / 2916人閱讀

摘要:實(shí)現(xiàn)數(shù)組更多的高階函數(shù)吾輩的博客原文場(chǎng)景雖說(shuō)人人平等,但有些人更加平等。若是有一篇適合萌新閱讀的自己實(shí)現(xiàn)數(shù)組更多操作的文章,情況或許會(huì)發(fā)生一些變化。類似于的初始值,但它是一個(gè)函數(shù),避免初始值在所有分組中進(jìn)行累加。

JavaScript 實(shí)現(xiàn)數(shù)組更多的高階函數(shù)
吾輩的博客原文: https://blog.rxliuli.com/p/fc...
場(chǎng)景
雖說(shuō)人人平等,但有些人更加平等。

為什么有了 Lodash 這種通用函數(shù)工具庫(kù),吾輩要寫(xiě)這篇文章呢?吾輩在 SegmentFault 上經(jīng)常看到關(guān)于 JavaScript 數(shù)組的相關(guān)疑問(wèn),甚至于,相同類型的問(wèn)題,只是數(shù)據(jù)變化了一些,就直接提出了一個(gè)新的問(wèn)題(實(shí)際上,對(duì)自身并無(wú)幫助)。簡(jiǎn)單搜索了一下 Array,居然有 2360+ 條的結(jié)果,足可見(jiàn)這類問(wèn)題的頻率之高。若是有一篇適合 JavaScript 萌新閱讀的自己實(shí)現(xiàn)數(shù)組更多操作的文章,情況或許會(huì)發(fā)生一些變化。

下面吾輩便來(lái)實(shí)現(xiàn)以下幾種常見(jiàn)的操作

uniqueBy: 去重

sortBy: 排序

filterItems: 過(guò)濾掉一些元素

diffBy: 差異

groupBy: 分組

arrayToMap: Array 轉(zhuǎn)換為 Map

遞歸操作

前言:
你至少需要了解 ES6 的一些特性你才能愉快的閱讀
uniqueBy: 去重

相關(guān)問(wèn)題

javascript 怎么實(shí)現(xiàn)多種數(shù)據(jù)類型的數(shù)組去重?

JS 有沒(méi)有比較高效的數(shù)組去重的方法?

/**
 * js 的數(shù)組去重方法
 * @param arr 要進(jìn)行去重的數(shù)組
 * @param kFn 唯一標(biāo)識(shí)元素的方法,默認(rèn)使用 {@link returnItself}
 * @returns 進(jìn)行去重操作之后得到的新的數(shù)組 (原數(shù)組并未改變)
 */
function uniqueBy(arr, kFn = val => val) {
  const set = new Set()
  return arr.filter((v, ...args) => {
    const k = kFn(v, ...args)
    if (set.has(k)) {
      return false
    }
    set.add(k)
    return true
  })
}

使用

console.log(uniqueBy([1, 2, 3, "1", "2"])) // [ 1, 2, 3, "1", "2" ]
console.log(uniqueBy([1, 2, 3, "1", "2"], i => i + "")) // [ 1, 2, 3 ]
sortBy: 排序

相關(guān)問(wèn)題

js 中如何對(duì)含有特殊字符的數(shù)組進(jìn)行排序?

以下數(shù)組怎么按名稱排序

/**
 * 快速根據(jù)指定函數(shù)對(duì)數(shù)組進(jìn)行排序
 * 注: 使用遞歸實(shí)現(xiàn),對(duì)于超大數(shù)組(其實(shí)前端的數(shù)組不可能特別大吧?#笑)可能造成堆棧溢出
 * @param arr 需要排序的數(shù)組
 * @param kFn 對(duì)數(shù)組中每個(gè)元素都產(chǎn)生可比較的值的函數(shù),默認(rèn)返回自身進(jìn)行比較
 * @returns 排序后的新數(shù)組
 */
function sortBy(arr, kFn = v => v) {
  // TODO 此處為了讓 typedoc 能生成文檔而不得不加上類型
  const newArr = arr.map((v, i) => [v, i])
  function _sort(arr, fn) {
    // 邊界條件,如果傳入數(shù)組的值
    if (arr.length <= 1) {
      return arr
    }
    // 根據(jù)中間值對(duì)數(shù)組分治為兩個(gè)數(shù)組
    const medianIndex = Math.floor(arr.length / 2)
    const medianValue = arr[medianIndex]
    const left = []
    const right = []
    for (let i = 0, len = arr.length; i < len; i++) {
      if (i === medianIndex) {
        continue
      }
      const v = arr[i]
      if (fn(v, medianValue) <= 0) {
        left.push(v)
      } else {
        right.push(v)
      }
    }
    return _sort(left, fn)
      .concat([medianValue])
      .concat(_sort(right, fn))
  }
  return _sort(newArr, ([t1, i1], [t2, i2]) => {
    const k1 = kFn(t1, i1, arr)
    const k2 = kFn(t2, i2, arr)
    if (k1 === k2) {
      return 0
    } else if (k1 < k2) {
      return -1
    } else {
      return 1
    }
  }).map(([_v, i]) => arr[i])
}

使用

console.log(sortBy([1, 3, 5, 2, 4])) // [ 1, 2, 3, 4, 5 ]
console.log(sortBy([1, 3, 5, "2", "4"])) // [ 1, "2", 3, "4", 5 ]
console.log(sortBy([1, 3, 5, "2", "4"], i => -i)) // [ 5, "4", 3, "2", 1 ]
filterItems: 過(guò)濾掉一些元素

相關(guān)問(wèn)題

過(guò)濾數(shù)組子集

對(duì)比兩組對(duì)象數(shù)組 根據(jù)元素內(nèi)某一屬性是否相等過(guò)濾數(shù)組

/**
 * 從數(shù)組中移除指定的元素
 * 注: 時(shí)間復(fù)雜度為 1~3On
 * @param arr 需要被過(guò)濾的數(shù)組
 * @param deleteItems 要過(guò)濾的元素?cái)?shù)組
 * @param kFn 每個(gè)元素的唯一鍵函數(shù)
 */
function filterItems(arr, deleteItems, kFn = v => v) {
  const kSet = new Set(deleteItems.map(kFn))
  return arr.filter((v, i, arr) => !kSet.has(kFn(v, i, arr)))
}

使用

console.log(filterItems([1, 2, 3, 4, 5], [1, 2, 0])) // [ 3, 4, 5 ]
console.log(filterItems([1, 2, 3, 4, 5], ["1", "2"], i => i + "")) // [ 3, 4, 5 ]
diffBy: 差異

相關(guān)問(wèn)題

JS 求兩個(gè)對(duì)象數(shù)組的差集

JavaScript 數(shù)組系列問(wèn)題:數(shù)組差集

/**
 * 比較兩個(gè)數(shù)組的差異
 * @param left 第一個(gè)數(shù)組
 * @param right 第二個(gè)數(shù)組
 * @param kFn 每個(gè)元素的唯一標(biāo)識(shí)產(chǎn)生函數(shù)
 * @returns 比較的差異結(jié)果
 */
function diffBy(left, right, kFn = v => v) {
  // 首先得到兩個(gè) kSet 集合用于過(guò)濾
  const kThanSet = new Set(left.map(kFn))
  const kThatSet = new Set(right.map(kFn))
  const leftUnique = left.filter((v, ...args) => !kThatSet.has(kFn(v, ...args)))
  const rightUnique = right.filter(
    (v, ...args) => !kThanSet.has(kFn(v, ...args)),
  )
  const kLeftSet = new Set(leftUnique.map(kFn))
  const common = left.filter((v, ...args) => !kLeftSet.has(kFn(v, ...args)))
  return { left: leftUnique, right: rightUnique, common }
}

使用

console.log(diffBy([1, 2, 3], [2, 3, 4])) // { left: [ 1 ], right: [ 4 ], common: [ 2, 3 ] }
console.log(diffBy([1, 2, 3], ["2", 3, 4])) // { left: [ 1, 2 ], right: [ "2", 4 ], common: [ 3 ] }
console.log(diffBy([1, 2, 3], ["2", 3, 4], i => i + "")) // { left: [ 1 ], right: [ 4 ], common: [ 2, 3 ] }
groupBy: 分組

相關(guān)問(wèn)題

求一個(gè)數(shù)組按屬性分組的方法

js 數(shù)組分組?

/**
 * js 數(shù)組按照某個(gè)條件進(jìn)行分組
 *
 * @param arr 要進(jìn)行分組的數(shù)組
 * @param kFn 元素分組的唯一標(biāo)識(shí)函數(shù)
 * @param vFn 元素分組的值處理的函數(shù)。第一個(gè)參數(shù)是累計(jì)值,第二個(gè)參數(shù)是當(dāng)前正在迭代的元素,如果你使用過(guò) {@link Array#reduce} 函數(shù)的話應(yīng)該對(duì)此很熟悉
 * @param init 每個(gè)分組的產(chǎn)生初始值的函數(shù)。類似于 reduce 的初始值,但它是一個(gè)函數(shù),避免初始值在所有分組中進(jìn)行累加。
 * @returns 元素標(biāo)識(shí) => 數(shù)組映射 Map
 */
function groupBy(
  arr,
  kFn = v => v,
  /**
   * 默認(rèn)的值處理函數(shù)
   * @param res 最終 V 集合
   * @param item 當(dāng)前迭代的元素
   * @returns 將當(dāng)前元素合并后的最終 V 集合
   */
  vFn = (res, item) => {
    res.push(item)
    return res
  },
  init = () => [],
) {
  // 將元素按照分組條件進(jìn)行分組得到一個(gè) 條件 -> 數(shù)組 的對(duì)象
  return arr.reduce((res, item, index, arr) => {
    const k = kFn(item, index, arr)
    // 如果已經(jīng)有這個(gè)鍵了就直接追加, 否則先將之初始化再追加元素
    if (!res.has(k)) {
      res.set(k, init())
    }
    res.set(k, vFn(res.get(k), item, index, arr))
    return res
  }, new Map())
}

使用

console.log(groupBy([1, 2, 2, 2, 4, 4, 5, 5, 6], i => i)) // Map { 1 => [ 1 ],? 2 => [ 2, 2, 2 ],? 4 => [ 4, 4 ],? 5 => [ 5, 5 ],? 6 => [ 6 ] }
console.log(groupBy([1, 2, 2, 2, 4, 4, 5, 5, 6], i => i % 2 === 0)) // Map { false => [ 1, 5, 5 ], true => [ 2, 2, 2, 4, 4, 6 ] }
console.log(
  groupBy(
    [1, 2, 2, 2, 4, 4, 5, 5, 6],
    i => i % 2 === 0,
    (res, i) => res.add(i),
    () => new Set(),
  ),
) // Map { false => Set { 1, 5 }, true => Set { 2, 4, 6 } }
arrayToMap: 轉(zhuǎn)換為 Map

相關(guān)問(wèn)題

js 怎么把數(shù)組下面的對(duì)象里面的兩個(gè)字段取出來(lái)組成一個(gè)新的對(duì)象,key:value 形式

/**
 * 將數(shù)組映射為 Map
 * @param arr 數(shù)組
 * @param k 產(chǎn)生 Map 元素唯一標(biāo)識(shí)的函數(shù),或者對(duì)象元素中的一個(gè)屬性名
 * @param v 產(chǎn)生 Map 值的函數(shù),默認(rèn)為返回?cái)?shù)組的元素,或者對(duì)象元素中的一個(gè)屬性名
 * @returns 映射產(chǎn)生的 map 集合
 */
export function arrayToMap(arr, k, v = val => val) {
  const kFn = k instanceof Function ? k : item => Reflect.get(item, k)
  const vFn = v instanceof Function ? v : item => Reflect.get(item, v)
  return arr.reduce(
    (res, item, index, arr) =>
      res.set(kFn(item, index, arr), vFn(item, index, arr)),
    new Map(),
  )
}

使用

const county_list = [
  {
    id: 1,
    code: "110101",
    name: "東城區(qū)",
    citycode: "110100",
  },
  {
    id: 2,
    code: "110102",
    name: "西城區(qū)",
    citycode: "110100",
  },
  {
    id: 3,
    code: "110103",
    name: "崇文區(qū)",
    citycode: "110100",
  },
]
console.log(arrayToMap(county_list, "code", "name")) // Map { "110101" => "東城區(qū)", "110102" => "西城區(qū)", "110103" => "崇文區(qū)" }
console.log(arrayToMap(county_list, ({ code }) => code, ({ name }) => name)) // Map { "110101" => "東城區(qū)", "110102" => "西城區(qū)", "110103" => "崇文區(qū)" }
遞歸

相關(guān)問(wèn)題

復(fù)雜數(shù)組去重

JavaScript 數(shù)組中包含數(shù)組如何去重?

以上種種操作皆是對(duì)一層數(shù)組進(jìn)行操作,如果我們想對(duì)嵌套數(shù)組進(jìn)行操作呢?例如上面這兩個(gè)問(wèn)題?其實(shí)問(wèn)題是類似的,只是遞歸遍歷數(shù)組而已。

/**
 * js 的數(shù)組遞歸去重方法
 * @param arr 要進(jìn)行去重的數(shù)組
 * @param kFn 唯一標(biāo)識(shí)元素的方法,默認(rèn)使用 {@link returnItself},只對(duì)非數(shù)組元素生效
 * @returns 進(jìn)行去重操作之后得到的新的數(shù)組 (原數(shù)組并未改變)
 */
function deepUniqueBy(arr, kFn = val => val) {
  const set = new Set()
  return arr.reduce((res, v, i, arr) => {
    if (Array.isArray(v)) {
      res.push(deepUniqueBy(v))
      return res
    }
    const k = kFn(v, i, arr)
    if (!set.has(k)) {
      set.add(k)
      res.push(v)
    }
    return res
  }, [])
}

使用

const testArr = [
  1,
  1,
  3,
  "hello",
  [3, 4, 4, "hello", "5", [5, 5, ["a", "r"]]],
  {
    key: "test",
  },
  4,
  [3, 0, 2, 3],
]
console.log(deepUniqueBy(testArr)) // [ 1,? 3,? "hello",? [ 3, 4, "hello", "5", [ 5, [Object] ] ],? { key: "test" },? 4,? [ 3, 0, 2 ] ]
反例

事實(shí)上,目前 SegmentFault 上存在著大量低質(zhì)量且重復(fù)的問(wèn)題及回答,關(guān)于這點(diǎn)確實(shí)比不上 StackOverflow。下面是兩個(gè)例子,可以看一下能否發(fā)現(xiàn)什么問(wèn)題

js 怎么把數(shù)組下面的對(duì)象里面的兩個(gè)字段取出來(lái)組成一個(gè)新的對(duì)象,key:value 形式

JS 中處理 JSON 數(shù)據(jù)重復(fù)問(wèn)題,取出里面 name 字段數(shù)值相同的作為一個(gè)數(shù)組;不相同的作為一個(gè)數(shù)組?

事實(shí)上,不管是問(wèn)題還是答案,都沒(méi)有突出核心 -- Array 映射為 Map/Array 分組,而且這種問(wèn)題和答案還層出不窮。如果對(duì) Array 的 API 都沒(méi)有看過(guò)一遍就來(lái)詢問(wèn)的話,對(duì)于幫助者來(lái)說(shuō)卻是太失禮了!

總結(jié)

JavaScript 對(duì)函數(shù)式編程支持很好,所以習(xí)慣高階函數(shù)于我們而言是一件好事,將問(wèn)題的本質(zhì)抽離出來(lái),而不是每次都局限于某個(gè)具體的問(wèn)題上。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/105360.html

相關(guān)文章

  • JavaScript 編程精解 中文第三版 五、高階函數(shù)

    摘要:高階函數(shù)如果一個(gè)函數(shù)操作其他函數(shù),即將其他函數(shù)作為參數(shù)或?qū)⒑瘮?shù)作為返回值,那么我們可以將其稱為高階函數(shù)。我們可以使用高階函數(shù)對(duì)一系列操作和值進(jìn)行抽象。高階函數(shù)有多種表現(xiàn)形式。腳本數(shù)據(jù)集數(shù)據(jù)處理是高階函數(shù)表現(xiàn)突出的一個(gè)領(lǐng)域。 來(lái)源:ApacheCN『JavaScript 編程精解 中文第三版』翻譯項(xiàng)目原文:Higher-Order Functions 譯者:飛龍 協(xié)議:CC BY-NC-...

    blastz 評(píng)論0 收藏0
  • 【重溫基礎(chǔ)】21.高階函數(shù)

    摘要:歡迎您的支持系列目錄復(fù)習(xí)資料資料整理個(gè)人整理重溫基礎(chǔ)篇重溫基礎(chǔ)對(duì)象介紹重溫基礎(chǔ)對(duì)象介紹重溫基礎(chǔ)介紹重溫基礎(chǔ)相等性判斷重溫基礎(chǔ)閉包重溫基礎(chǔ)事件本章節(jié)復(fù)習(xí)的是中的高階函數(shù),可以提高我們的開(kāi)發(fā)效率。 本文是 重溫基礎(chǔ) 系列文章的第二十一篇。 今日感受:想家。 本人自己整理的【Cute-JavaScript】資料,包含:【ES6/ES7/ES8/ES9】,【JavaScript基礎(chǔ)...

    wua_wua2012 評(píng)論0 收藏0
  • 一文帶你了解什么是JavaScript 函數(shù)式編程?

    摘要:前言函數(shù)式編程在前端已經(jīng)成為了一個(gè)非常熱門(mén)的話題。整個(gè)過(guò)程就是體現(xiàn)了函數(shù)式編程的核心思想通過(guò)函數(shù)對(duì)數(shù)據(jù)進(jìn)行轉(zhuǎn)換。高階函數(shù)函數(shù)式編程傾向于復(fù)用一組通用的函數(shù)功能來(lái)處理數(shù)據(jù),它通過(guò)使用高階函數(shù)來(lái)實(shí)現(xiàn)。 前言 函數(shù)式編程在前端已經(jīng)成為了一個(gè)非常熱門(mén)的話題。在最近幾年里,我們看到非常多的應(yīng)用程序代碼庫(kù)里大量使用著函數(shù)式編程思想。 本文將略去那些晦澀難懂的概念介紹,重點(diǎn)展示在 JavaScrip...

    acrazing 評(píng)論0 收藏0
  • [前端漫談_3] 從 filter 聊到 Promise

    摘要:前言在學(xué)習(xí)前端的時(shí)候,我總是能聽(tīng)到很多高級(jí)詞匯,比如今天會(huì)聊到的函數(shù)式編程高階函數(shù)。接下來(lái)我們看看,高階函數(shù)有可能會(huì)遇到的問(wèn)題,又如何去解決。 前言 在學(xué)習(xí)前端的時(shí)候,我總是能聽(tīng)到很多高級(jí)詞匯,比如今天會(huì)聊到的 函數(shù)式編程(Functional Programming) & 高階函數(shù) (Higher-order function) 。但是當(dāng)你真正的理解什么是 函數(shù)式編程 & 高階函數(shù) ...

    crossoverJie 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<