菜单 学习猿地 - LMONKEY

VIP

开通学习猿地VIP

尊享10项VIP特权 持续新增

知识通关挑战

打卡带练!告别无效练习

接私单赚外块

VIP优先接,累计金额超百万

学习猿地私房课免费学

大厂实战课仅对VIP开放

你的一对一导师

每月可免费咨询大牛30次

领取更多软件工程师实用特权

入驻
76
0

算法 序列提取

原创
05/13 14:22
阅读数 331

程序不仅仅是存储数据,通常具备描述数据关系(数据结构),操作数据行为(算法)。
本文演示一维数组通过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,依次累计求值得到一个新数组

  1. 查找出所有连续元素
  2. 在本连续子序列第一次出现的连续元素时,创建二维数组
  3. 依次将每个源数组元素根据是否连续分别加入新数组的二维数组元素或一维数组队尾

实现

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 方法得到想要的结果

发表评论

0/200
76 点赞
0 评论
收藏
为你推荐 换一批