程序不仅仅是存储数据,通常具备描述数据关系(数据结构),操作数据行为(算法)。
本文演示一维数组通过reduce
方法转二维,达到符合需求改变数据关系的小程序。
问题
实现一个方法,将一维数组内的连续序列,变成该数组内的二维数组元素
// 输入
[1,1,1,2,3,4,5,8,10,22,24,25,26,66]
// 输出
[1,1,[1,2,3,4,5],8,10,22,[24,25,26],66]
思路
借用数组的原型方法reduce,依次累计求值得到一个新数组
- 查找出所有连续元素
- 在本连续子序列第一次出现的连续元素时,创建二维数组
- 依次将每个源数组元素根据是否连续分别加入新数组的二维数组元素或一维数组队尾
实现
Array.prototype.reduce()
原型方法
arr.reduce(callback(accumulator, currentValue[, index[, array]])[, initialValue])
回调callback
参数 accumulator (acc)
当前累计器参数,initialValue
初始化累计值
current Value (cur)
当前值 current Index (idx)
当前索引 source Array (src)
源数组
function reducer (acc, v, i,arr) {
// 1.过滤所有连续数
if ((arr[i + 1] - arr[i] == 1)|| (arr[i] - arr[i - 1] == 1)) {
// 2.创建二维数组
if (i == 0 || arr[i] - arr[i - 1] != 1) {
acc.push([])
}
// 3.向二维数组内追加元素
acc[acc.length - 1].push(v)
} else {
// 4.一维数组项继续加入不连续数
acc.push(v)
}
return acc
}
测试
var arr = [4, 1, 1, 1, 2, 3, 4, 5, 8, 10, 22, 24, 25, 26, 66, 67]
console.log(arr.reduce(reducer,[]))
结果
[ 4, 1, 1, [ 1, 2, 3, 4, 5 ], 8, 10, 22, [ 24, 25, 26 ], [ 66, 67 ] ]
扩展
对于数组[1,2, 3, 5, 6, 8, 10,11,12]
,数字连续用- 表示,转成[1-3,5-6,8,10-12]
?
分析: 先处理分组后用 join
拼接
var aList = [1,2, 3, 5, 6, 8, 10,11,12]
var str = aList.reduce(reducer,[]).map(v => Array.isArray(v) ? v.join('-') : v)
console.log(aList)
console.log(str)
输出
[ 1, 2, 3, 5, 6, 8, 10, 11, 12 ]
[ '1-2-3', '5-6', 8, '10-11-12' ]
其它
此例主要是考虑到了源序列顺序未变,遇到连续数则就地重组追加,
亦可使用for循环+指针计算连续起始索引,结合slice
方法得到想要的结果