【重學】數(shù)組扁平化械哟,亂序

目錄:
數(shù)組扁平化
數(shù)組亂序
reduce()的妙用
git復習:rebase映凳,cherry-pick

(1)數(shù)組扁平化

1. flat()
- Array.prototype.flat()
- 參數(shù)是:要拉平的層數(shù)
- 參數(shù)是 Infinity 時表示不管嵌套多少層录别,都轉(zhuǎn)成一元數(shù)組
- flat() 不會改變原數(shù)組耕渴,該方法會返回一個新數(shù)組
- 如果原數(shù)組有空位拘悦,flat()方法會跳過空位
- 代碼:
const arr = [1, [2, 3, [4, 5, [6,7]]]] // [1,2,3,4,5,6,7]
const res = arr.flat(Infinity) // 參數(shù)表示展開的層數(shù),如果是Infinity表示不管多少層都轉(zhuǎn)成一元數(shù)組
console.log(res)


2. flatMap()
- flatMap()表示相對數(shù)組執(zhí)行 map() 方法橱脸,在執(zhí)行 flat()方法
- 參數(shù):第一個參數(shù)是一個遍歷函數(shù)础米,函數(shù)的參數(shù)一次是 value index array
- flatMap()方法還可以有第二個參數(shù)分苇,用來綁定遍歷函數(shù)里面的this
- flatMap()也不會改變原數(shù)組,會返回一個新的數(shù)組
- 注意:flatMap()默認之展開一層
- 代碼:
const arr = [1, 2, 3]
const res = arr.flatMap(i => [i, i*2]) // [1, 2, 2, 4, 3, 6]
// 相當于:[[1, 2], [2, 4], [3, 6]]
console.log(res)
2. 遞歸
recursion:遞歸

const arr = [1, [2, 3, [4, [5]]]]
function flat(arr) {
    let result = []
    for(let i = 0, len = arr.length; i < len; i++) {
        if(Array.isArray(arr[i])) { // 如果還是數(shù)組椭盏,遞歸
            result = result.concat(flat(arr[i]))
        } 
        else {
            result.push(arr[i])
        }
    }
    return result
}
const res = flat(arr)
console.log(res)
3. toString
- 如果數(shù)組元素都是數(shù)值(注意所有的數(shù)組中的所有元素都要是數(shù)字)组砚,可以使用toString()
- 然而這種方法使用的場景卻非常有限吻商,如果數(shù)組是 [1, '1', 2, '2'] 的話掏颊,這種方法就會產(chǎn)生錯誤的結(jié)果。


const arr = [1, [2, 3, [4, [5]]]]
function flat(arr) {
    return arr.toString().split(',').map(item => +item)
    //  arr.toString()數(shù)組的字符串形式艾帐,會展平乌叶。      =>  1,2,3,4,5
    // arr.toString().split(',')以,為分隔符柒爸,將字符串轉(zhuǎn)成數(shù)組  ["1", "2", "3", "4", "5"]
    // +item相當于Number(item)
}
const res = flat(arr)
console.log(res)
4. 使用reduce()

var arr = [1, [2, [3, 4]]];
function flatten(arr) {
    return arr.reduce(function(prev, next){
        return prev.concat(Array.isArray(next) ? flatten(next) : next)
    }, [])
  // 這里指定了初始值是 []
  // prev = []
  // next = 1准浴,因為prev初始值是空數(shù)組,所以next的初始值是 1

  // reduce((accumulate, currentValue, index, arr) => {....}, [])
  // 第一個參數(shù):是一個函數(shù)
    // 第一個參數(shù):累積變量捎稚,默認是數(shù)組的第一個元素
    // 第二個參數(shù):當前變量乐横,默認是數(shù)組的第二個元素
    // 第三個參數(shù):當前位置(當前變量在數(shù)組中的位置)
    // 第四個參數(shù):原數(shù)組
  // 第二個參數(shù):累積變量的初始值,注意如果指定了初始值今野,那么當前變量就從數(shù)組的第一個元素開始
}

console.log(flatten(arr))
4. 使用 ...展開運算符

let arr = [1, [2, [3, 4]]];
function flat(arr) {
  while (arr.some(item => Array.isArray(item))) { // 循環(huán)判斷是不是數(shù)組葡公,是數(shù)組就展開
    arr = [].concat(...arr); // 每次都扁平一層
  }
  return arr;
}
console.log(flat(arr))

https://github.com/mqyqingfeng/Blog/issues/36

(2)數(shù)組亂序

  • shuffle:洗牌
前置知識:
1. sort()
- sort()默認是按字典就行排序,數(shù)字會先被成字符串条霜,改變原數(shù)組催什,沒有返回值
- 如果想按照自定義的方式排序,參數(shù)可以是一個函數(shù)
- 參數(shù)函數(shù)有兩個參數(shù)(兩個比較的數(shù)組成員)
    - 返回值大于0宰睡,表示第一個成員排在第二個成員后面 (a-b>0蒲凶,則a排在b后面)
    - 返回值小于0,表示第一個成員排在第二個成員前面
    - 返回值等于0拆内,位置不變
- arr.sort((a, b) => a - b ) 升序
- arr.sort((a, b) => b - a ) 降序


2. js中不加分號的注意事項:
- 小括號開頭的前一條語句(注意前面要是語句旋圆,表達式不受影響)
- 中括號開頭的前一條語句
解決方法:在小括號或者中括號前面加上分號


哪些地方會用到亂序:
1. 換一批
2. 猜你喜歡
3. 中獎方案

方法1:
arr.sort(() => Math.random() - .5)


function a() {
  const arr = [1, 2, 3, 4, 5]
  arr.sort(() => Math.random() - .5)  // 因為Math.random的值區(qū)間是[0, 1) 所以 這里大于0和小于0的概率都是50%
  // sort自定義排序時接收一個函數(shù)作為參數(shù)
  // 函數(shù)返回值大于0,表示兩個比較的成員麸恍,第一個排在第二個的后面
  // 函數(shù)返回值小于0臂聋,表示兩個比較的成員,第一個排在第二個的前面
  // 函數(shù)返回值等于0或南,表示兩個比較的成員孩等,位置不變
  // 當小數(shù)是0點幾時,可以省略前面的0
  console.log(arr)
}


-----------
存在問題:
1. 概率不均等
2. 造成概率不均等的原因是采够,sort底層實現(xiàn)是用了插入排序
3. 具體就是當無序部分插入到有序部分的元素肄方,一旦找到位置,剩下的元素就沒有在和緩存的值就行比較了
4. 沒有機會比較所有元素蹬癌,所以得不到完全隨機的結(jié)果
如下:
const times = [0, 0, 0, 0, 0, 0]
for(i = 0; i < 100000; i++) {
    const arr = [1, 2, 3, 4, 5, 6]
    arr.sort(() => Math.random() - 0.5)
    times[arr[5] - 1] ++  
    // times[arr[5] - 1] ++ 表示arr數(shù)組最后一個位置上权她,各數(shù)字出現(xiàn)的次數(shù)
    // 當arr[5]是6時虹茶,times[5]位置的值+1,就是arr[5]是6的次數(shù)+1
}
console.log(times)
// [19480, 5174, 15619, 14188, 18880, 26659] 概率分配不均隅要,arr[5]是2的概率明顯小了很多



-----------
sort排序源碼:
- 各個瀏覽器的sort()方法的實現(xiàn)方法不同
- v8中
  - 當數(shù)組長度小于10時蝴罪,用的是插入排序
  - 否則,使用的是插入排序和快速排序的混合排序



-----------
插入排序
- 分類:
  - 直接插入排序:順序發(fā)定位插入位置
  - 二分插入排序:二分法定位插入位置
  -   希爾排序  :縮小增量步清,多遍插入排序



-----------
直接插入排序:
- 插入排序的思想:從無序數(shù)組中取出一個值要门,插入到有序數(shù)組中,插入后有序數(shù)組仍然有序(打牌)
- 原理:
  1. 將數(shù)組分成兩部分廓啊,左邊是有序數(shù)組(最初只有一個元素)欢搜,右邊是無序數(shù)組(所以循環(huán)是從1開始,因為有序部分初始有一個元素)
  2. 從右邊的無序部分依次取出一個值谴轮,插入到有序部分炒瘟,直到取完無序部分
  3. 如果找有序部分的插入位置?:
    1. 先緩存需要插入的無序部分的值第步,用一個變量來緩存 let temp = arr[i]
    2. 從有序部分的最后位置找(arr[i - 1])疮装,如果arr[i - 1] > arr[i] 則該元素往后移動一位
    3. 如果有序該位置仍然比需要插入的值大,有序中該位置的值粘都,也后移動一位廓推,直到 j>=0
- 代碼:
// 直接插入排序
const arr = [1, 4, 3, 2]
const insert_sort = (arr) => {
    for(let i = 1, len = arr.length; i < len; i++) { // 循環(huán)數(shù)組的無序部分,從1開始驯杜,因為假設(shè)初始化時有序部分有一個元素
        let temp = arr[i] // 緩存需要插入有序部分的這個無序部分的值受啥,因為有序部分可能會往后移動位置,將其覆蓋
        let j = i - 1 // 有序部分的最后一個元素的位置鸽心,有序部分從最后的位置依次往前查找需要插入的位置
        while(j >= 0 && arr[j] > temp) { // 有序部分循環(huán)條件
            arr[j+1] = arr[j] // 有序該位置值大于temp滚局,則往后移動一位
            j-- // 依次往前查找
        }
        arr[j+1] = temp // 循環(huán)完后,j+1就是需要插入的位置顽频,因為條件是大于temp藤肢,不滿足時,j+1就是要插入的位置
    }
    return arr // 最后返回數(shù)組
}
console.log(insert_sort(arr))

亂序排序改進

Fisher–Yates

1. 使用sort(() =>  Math.random() - .5)存在的問題就是不能完全實現(xiàn)全部元素的比較糯景,造成概率不均等
2. 為什么叫 Fisher–Yates 呢嘁圈?
  - 因為這個算法是由 Ronald Fisher 和 Frank Yates 首次提出的。
3.shuffle:是洗牌的意思

4.Fisher–Yates的原理:
- 首先選润盎础(數(shù)組最后一個位置)的元素和(數(shù)組長度隨機位置)上的元素交換
- 接著選茸钭 (數(shù)組倒數(shù)第二個位置)的元素和(除去最后一個位置剩下的數(shù)組位置)上的元素交換
- 重復以上步驟,直到length >= 1

5.代碼
// 數(shù)組亂序
const arr = [1, 2, 3, 4, 5, 6]
function shuffle(arr) {
    let length = arr.length
    while(length > 1) {
        const pivot = Math.floor(Math.random() * length--) 
        // 1. 注意這里是先賦值怠惶,再減 1涨缚,即Math.floor(Math.random() * 6) 
        // (Math.random() * 6的區(qū)間[0, 6)
        // Math.floor(Math.random() * 6) 區(qū)間是 [0-5]

        // 2. 語句以分號結(jié)尾,一個分號就表示一個語句結(jié)束策治。所以這里賦值語句后面記得加分號
        // 3. ;[arr[pivot], arr[length]] = [arr[length], arr[pivot]]這里條語句前加上分號脓魏,因為前面也是語句
        // 在小括號開頭兰吟,或者中括號開頭的語句,前面的語句末尾需要加分號茂翔,或者加到本條語句前面
        //4. const pivot = Math.floor(Math.random() * length--); 這樣也行
        ;[arr[pivot], arr[length]] = [arr[length], arr[pivot]] // 這里的length是減1之后的length
        // const temp = arr[length]
        // arr[length] = arr[pivot]
        // arr[pivot] = temp
    }
    return arr
}
console.log(shuffle(arr))

https://juejin.im/post/5d004ad95188257c6b518056#heading-2

(3)reduce()使用技巧

reduce()

(1) 概念
- reduce()默認按照字典排序
- reduce(function(reduce, currentValue, currentIndex, arr), initial)
- 第一個參數(shù)是函數(shù):
  - 函數(shù)第一個參數(shù):累計變量混蔼,默認是數(shù)組的第一項
  - 函數(shù)第二個參數(shù):當前變量,默認是數(shù)組的第二項(如給定reduce第二個參數(shù)(累積變量初始值)珊燎,則當前變量從第一項開始)
  - 函數(shù)第三個參數(shù):當前位置惭嚣,(第二個參數(shù)的下標)
  - 函數(shù)第四個參數(shù):原數(shù)組
- 第二個參數(shù)是(累計變量初始值),如果給定累計變量初始值俐末,當前變量就從數(shù)組第一項開始

(2) 用法
1. 累加

2. 將數(shù)組轉(zhuǎn)化成對象
const arr = [{id: 1, name: 'wang'}, {id: 2, name: 'zhang'}]
const res = arr.reduce((pre, cur, i, arr) => {
  return {...pre, [cur.id]: cur}
}, {})
console.log(res)


(3) 實現(xiàn)數(shù)組扁平化
const arr = [1, [2, [3, [4, 5]], 6], 7]
function flat(arr) {
  return arr.reduce((prev, current, index, arr) => {
    return prev.concat(Array.isArray(current) ? flat(current) : current)
  }, [])
}
const res = flat(arr)
console.log(res)

https://juejin.im/post/5cbc23def265da037b610ec6#heading-18

https://juejin.im/post/5d073414f265da1b6029037f

(4)git

(一)初次運行g(shù)it前的配置

(1) 用戶信息
- 第一步就是設(shè)置(用戶名)和(郵件地址)
- 如果使用了--global料按,該命令只需運行一次奄侠,之后無論在什么系統(tǒng)上做任何事情卓箫,git都會使用那些信息
- 當你想針對特定項目使用不同的用戶名稱與郵件地址時,可以在那個項目目錄下運行沒有 --global 選項的命令來配置垄潮。
$ git config --global user.name "John Doe"
$ git config --global user.email johndoe@example.com


(2) 文本編輯器
- 當用戶信息配置完后烹卒,可以配置文本編輯器,用戶使用git輸入信息時弯洗,會調(diào)用文本編輯器
- 默認調(diào)用的是 (vim)旅急,如果想自定義可以輸入以下命令:
$ git config --global core.editor emacs  // 使用Emacs編輯器


(3) 檢查配置信息
- 如果想要檢查你的配置,可以使用 git config --list 命令來列出所有 Git 當時能找到的配置
$ git config --list
(1) git log
- git log:顯示從最近到最遠的提交日志
- git log --pretty=oneline --graph
- // --pretty=oneline 將commit 信息簡化成一行顯示
- // --graph命令可以看到分支合并圖牡整。 -------------( graph是圖表的意思 )


(2) git reflog
- gitt reflog:記錄幾乎所有本地倉庫的改變
- 可以用來重返未來(git reset --hard comit_id之后后悔)


(3) git reset
- git reset --hard commit_id
- git reset --hard HEAD^ // 回退到上一個commit
- 當前版本   ( HEAD )
- 上一個版本 ( HEAD^ )或者  ( HEAD~1 )
- 上上個版本 ( HEAD^^ ) 或者 ( HEAD~2 )
(4) git rebase
- 不同分支:變基
- 同一分支:合并多個提交
git rebase變基
- 不同分支的處理是變基
- git rebase master  // 把當前分支變基到master分支
git rebase進入交互模式 
- 同一分支是進入交互模式

- git rebase -i  [startpoint]  [endpoint] 
- git rebase -i HEAD~3  表示將最新的三個提交進入交互式界面
// [startpoint]  [endpoint]這個是一個 (前開后閉區(qū)間)
// 如果不指定[endpoint]藐吮,則該區(qū)間的終點默認是當前分支HEAD所指向的commit(
// i:是 (interactive)交互的意思

pick:保留該commit(縮寫:p)
reword:保留該commit,但我需要修改該commit的注釋(縮寫:r)
edit:保留該commit, 但我要停下來修改該提交(不僅僅修改注釋)(縮寫:e)
squash:將該commit和前一個commit合并(縮寫:s)
fixup:將該commit和前一個commit合并逃贝,但我不要保留該提交的注釋信息(縮寫:f)
exec:執(zhí)行shell命令(縮寫:x)
drop:我要丟棄該commit(縮寫:d)

- squash:是粉碎的意思
- reword:改寫谣辞,修改措辭的意思

http://www.reibang.com/p/4a8f4af4e803

https://git-scm.com/book/zh/v2/%E8%B5%B7%E6%AD%A5-%E5%88%9D%E6%AC%A1%E8%BF%90%E8%A1%8C-Git-%E5%89%8D%E7%9A%84%E9%85%8D%E7%BD%AE

(5) git cherry-pick 摘櫻桃
- git cherry-pick:把其他分支的commit,移到當前分支
- git cherry-pick <commit id>

- 如果有沖突沐扳,首先需要解決沖突,解決沖突后需要git commit手動進行提交
- git add .后直接使用git cherry-pick --continue繼續(xù) // 繼續(xù)后泥从,可以修改提交的commit的命名

https://www.cnblogs.com/ludashi/p/8213550.html

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市沪摄,隨后出現(xiàn)的幾起案子躯嫉,更是在濱河造成了極大的恐慌,老刑警劉巖杨拐,帶你破解...
    沈念sama閱讀 218,607評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件祈餐,死亡現(xiàn)場離奇詭異,居然都是意外死亡哄陶,警方通過查閱死者的電腦和手機帆阳,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,239評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來奕筐,“玉大人舱痘,你說我怎么就攤上這事变骡。” “怎么了芭逝?”我有些...
    開封第一講書人閱讀 164,960評論 0 355
  • 文/不壞的土叔 我叫張陵塌碌,是天一觀的道長。 經(jīng)常有香客問我旬盯,道長台妆,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,750評論 1 294
  • 正文 為了忘掉前任胖翰,我火速辦了婚禮接剩,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘萨咳。我一直安慰自己懊缺,他們只是感情好,可當我...
    茶點故事閱讀 67,764評論 6 392
  • 文/花漫 我一把揭開白布培他。 她就那樣靜靜地躺著鹃两,像睡著了一般。 火紅的嫁衣襯著肌膚如雪舀凛。 梳的紋絲不亂的頭發(fā)上俊扳,一...
    開封第一講書人閱讀 51,604評論 1 305
  • 那天,我揣著相機與錄音猛遍,去河邊找鬼馋记。 笑死,一個胖子當著我的面吹牛懊烤,可吹牛的內(nèi)容都是我干的梯醒。 我是一名探鬼主播,決...
    沈念sama閱讀 40,347評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼奸晴,長吁一口氣:“原來是場噩夢啊……” “哼冤馏!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起寄啼,我...
    開封第一講書人閱讀 39,253評論 0 276
  • 序言:老撾萬榮一對情侶失蹤逮光,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后墩划,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體涕刚,經(jīng)...
    沈念sama閱讀 45,702評論 1 315
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,893評論 3 336
  • 正文 我和宋清朗相戀三年乙帮,在試婚紗的時候發(fā)現(xiàn)自己被綠了杜漠。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,015評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖驾茴,靈堂內(nèi)的尸體忽然破棺而出盼樟,到底是詐尸還是另有隱情,我是刑警寧澤锈至,帶...
    沈念sama閱讀 35,734評論 5 346
  • 正文 年R本政府宣布晨缴,位于F島的核電站,受9級特大地震影響峡捡,放射性物質(zhì)發(fā)生泄漏击碗。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,352評論 3 330
  • 文/蒙蒙 一们拙、第九天 我趴在偏房一處隱蔽的房頂上張望稍途。 院中可真熱鬧,春花似錦砚婆、人聲如沸械拍。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,934評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽殊者。三九已至与境,卻和暖如春验夯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背摔刁。 一陣腳步聲響...
    開封第一講書人閱讀 33,052評論 1 270
  • 我被黑心中介騙來泰國打工挥转, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人共屈。 一個月前我還...
    沈念sama閱讀 48,216評論 3 371
  • 正文 我出身青樓绑谣,卻偏偏與公主長得像,于是被迫代替她去往敵國和親拗引。 傳聞我的和親對象是個殘疾皇子借宵,可洞房花燭夜當晚...
    茶點故事閱讀 44,969評論 2 355

推薦閱讀更多精彩內(nèi)容