JS生成嵌套数组

https://img.mukewang.com/5bd51a3100017d4204180523.jpg

比如$scope.colsNum=3,生成一个$scope._outArray=[[5],[5],[2]]这样的数组。

这里是想把$scope.testArray生成一个嵌套的数组,这样也能实现,但觉得自己写的太啰嗦了,希望给一个更好的写法。


一只斗牛犬
浏览 1925回答 1
1回答

拉莫斯之舞

用 lodash如果用 lodash,很简单,一个函数就搞定const&nbsp;_&nbsp;=&nbsp;require("lodash");const&nbsp;result&nbsp;=&nbsp;_.chunk(data,&nbsp;colsNum);console.log(result);lodash 的 _.chunk() 源码回答完这个问题之后我突然好奇 lodash 是怎么实现的,所以我去翻了下它的源码,其中最关键的一段是&nbsp;&nbsp;while&nbsp;(index&nbsp;<&nbsp;length)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;result[resIndex++]&nbsp;=&nbsp;baseSlice(array,&nbsp;index,&nbsp;(index&nbsp;+=&nbsp;size)); &nbsp;&nbsp;}可以看出来,它采用的是 slice 的思想,每次取一段出来放在新数组中。 slice 它调用的&nbsp;baseSlice()&nbsp;在&nbsp;_baseSlice.js&nbsp;中,对应&nbsp;_.slice()&nbsp;方法,,实现的功能和&nbsp;Array.prototype.slice&nbsp;一致。这就有意思了,如果采用这种方式,就有办法使用函数式与法了——见自己写函数的第三个方法。自己写函数reduce当然自己写也可以,之前回答某个问题的时候写过,再写一次,用&nbsp;reduce&nbsp;再稍加处理。主要是保持两个数组,一个是结果数组,一个是当前组数组,不需要&nbsp;i&nbsp;变量,因为当前组数组的&nbsp;length&nbsp;就能取到数量信息。function&nbsp;groupByCols(data,&nbsp;cols)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;r&nbsp;=&nbsp;data.reduce((r,&nbsp;t)&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r.current.push(t);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(r.current.length&nbsp;===&nbsp;cols)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r.list.push(r.current); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r.current&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;r; &nbsp;&nbsp;&nbsp;&nbsp;},&nbsp;{&nbsp;list:&nbsp;[],&nbsp;current:&nbsp;[]&nbsp;});&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(r.current.length)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;r.list.push(r.current); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;r.list; }const&nbsp;result&nbsp;=&nbsp;groupByCols(data,&nbsp;colsNum);console.log(result);forEach其实&nbsp;reduce&nbsp;用在这里优势不明显,因为有最后一步处理,不能直接返回结果。所以用和你的方法类似的&nbsp;forEach改写function&nbsp;groupByCols2(data,&nbsp;cols)&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;list&nbsp;=&nbsp;[];&nbsp;&nbsp;&nbsp;&nbsp;let&nbsp;current&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;data.forEach(t&nbsp;=>&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current.push(t);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(current.length&nbsp;===&nbsp;cols)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.push(current); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;current&nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;});&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;(current.length)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;list.push(current); &nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;list; }slice + map 实现为了函数式写法,可能有些计算不太好理解,先看代码const&nbsp;result&nbsp;=&nbsp;Array.apply(null,&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;length:&nbsp;Math.ceil(data.length&nbsp;/&nbsp;cols) }).map((x,&nbsp;i)&nbsp;=>&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;return&nbsp;data.slice(i&nbsp;*&nbsp;cols,&nbsp;i&nbsp;*&nbsp;cols&nbsp;+&nbsp;cols); });Array.apply&nbsp;是为了生成一个长度为&nbsp;Math.ceil(data.length / cols)&nbsp;的数组,这就是循环次数(Math.ceil()&nbsp;用于保证有余数则进1)。然后在循环次数内通过&nbsp;slice()&nbsp;分段取出来。用 RxJsRxJs 用于异步处理数据还是挺方便的,用它的&nbsp;bufferCount()&nbsp;解决这种问题const&nbsp;Rx&nbsp;=&nbsp;require("rxjs");const&nbsp;out&nbsp;=&nbsp;Rx.Observable.from(data) &nbsp;&nbsp;&nbsp;&nbsp;.bufferCount(colsNum) &nbsp;&nbsp;&nbsp;&nbsp;.toArray() &nbsp;&nbsp;&nbsp;&nbsp;.do(console.log) &nbsp;&nbsp;&nbsp;&nbsp;.subscribe();这种方法适合异步或者 callback 处理(上面&nbsp;console.log&nbsp;那里传入的你的数据处理函数。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

JavaScript