1 回答

TA貢獻1820條經(jīng)驗 獲得超10個贊
用 lodash
如果用 lodash,很簡單,一個函數(shù)就搞定
const _ = require("lodash");const result = _.chunk(data, colsNum);console.log(result);
lodash 的 _.chunk() 源碼
回答完這個問題之后我突然好奇 lodash 是怎么實現(xiàn)的,所以我去翻了下它的源碼,其中最關(guān)鍵的一段是
while (index < length) { result[resIndex++] = baseSlice(array, index, (index += size)); }
可以看出來,它采用的是 slice 的思想,每次取一段出來放在新數(shù)組中。 slice 它調(diào)用的 baseSlice()
在 _baseSlice.js
中,對應 _.slice()
方法,,實現(xiàn)的功能和 Array.prototype.slice
一致。
這就有意思了,如果采用這種方式,就有辦法使用函數(shù)式與法了——見自己寫函數(shù)的第三個方法。
自己寫函數(shù)
reduce
當然自己寫也可以,之前回答某個問題的時候?qū)戇^,再寫一次,用 reduce
再稍加處理。
主要是保持兩個數(shù)組,一個是結(jié)果數(shù)組,一個是當前組數(shù)組,不需要 i
變量,因為當前組數(shù)組的 length
就能取到數(shù)量信息。
function groupByCols(data, cols) { const r = data.reduce((r, t) => { r.current.push(t); if (r.current.length === cols) { r.list.push(r.current); r.current = []; } return r; }, { list: [], current: [] }); if (r.current.length) { r.list.push(r.current); } return r.list; }const result = groupByCols(data, colsNum);console.log(result);
forEach
其實 reduce
用在這里優(yōu)勢不明顯,因為有最后一步處理,不能直接返回結(jié)果。所以用和你的方法類似的 forEach
改寫
function groupByCols2(data, cols) { const list = []; let current = []; data.forEach(t => { current.push(t); if (current.length === cols) { list.push(current); current = []; } }); if (current.length) { list.push(current); } return list; }
slice + map 實現(xiàn)
為了函數(shù)式寫法,可能有些計算不太好理解,先看代碼
const result = Array.apply(null, { length: Math.ceil(data.length / cols) }).map((x, i) => { return data.slice(i * cols, i * cols + cols); });
Array.apply
是為了生成一個長度為 Math.ceil(data.length / cols)
的數(shù)組,這就是循環(huán)次數(shù)(Math.ceil()
用于保證有余數(shù)則進1)。
然后在循環(huán)次數(shù)內(nèi)通過 slice()
分段取出來。
用 RxJs
RxJs 用于異步處理數(shù)據(jù)還是挺方便的,用它的 bufferCount()
解決這種問題
const Rx = require("rxjs");const out = Rx.Observable.from(data) .bufferCount(colsNum) .toArray() .do(console.log) .subscribe();
這種方法適合異步或者 callback 處理(上面 console.log
那里傳入的你的數(shù)據(jù)處理函數(shù)。
添加回答
舉報