利用JS实现一个同Excel表现的智能填充算法


Posted in Javascript onAugust 13, 2018

前言

本文介绍了关于利用JS实现同Excel表现的智能填充算法的相关内容,分享出供大家参考学习,下面话不多说了,来一起看看详细的介绍吧

利用JS实现一个同Excel表现的智能填充算法

在使用Excel的时候,发现它的“智能填充”功能非常有趣,能够智能地分析我当前的内容,然后准确预测出我期望得到的值。排除了AI的加成,发现这个功能其实也可以通过数学理论和简单代码来实现。经过一番折腾,终于用JS实现了大致的功能,然后我把它名为smart-predictor。

项目地址:https://github.com/jrainlau/s...(本地下载)

什么是“智能填充”?

首先我们来看两张gif图:

利用JS实现一个同Excel表现的智能填充算法

利用JS实现一个同Excel表现的智能填充算法

是不是很神奇?假设我有一组给定的数据[1, 3, 'aaa1', 'bbb2'] ,Excel的智能填充能够给我返回[5, 7, 'aaa2', 'bbb3', 9, 11 'aaa3', 'bbb4']这一组数据。

更厉害的是,智能填充不是简单地对数据进行递增,而是会对数据进行分组,每个分组按照自己的规则去进行递增,就比如说我们可以从[1, 2, 'x', 3]得到[3, 4, 'x', 4]

在明白这些结论之后,我们就可以去讨论它到底是怎么实现的。

Separator

我们用数组[1, 2, 'a1c', 'a2c']作为例子。当我们拿到这样一个数组的时候,第一步是要对其进行分析,分析数组内每个元素到底是一个数字,一段字符串,还是别的什么东西。分析完了,就要给他们都标注更详细的信息,然后把这些信息都组合起来。

比如数组元素1,可以被处理成下面这个样子:

{
 realValue: 1,
 numericValue: 1,
 splitParts: 'Number',
 index: 0
}

而数组元素a1c,则可以处理成这样:

{
 realValue: 'a1c',
 numericValue: 1,
 splitParts: ['a', 'c'],
 index: 2
}

代码请戳:separator.js

可以注意到,我会提取每一个元素的纯数字部分出来,然后把其余部分通过一个数组储存起来。这一切就是Separator所做的工作,我们最终会得到一个富含信息的新数组,然后继续我们的工作吧!

Classifier

智能填充的最小单位是“组”。当我们通过上一步得到一个富含信息的新数组之后,接下来就应该对它们进行合理的分组。分组的动作包含了两个细节:

  • 同一组的数据应该拥有一致的“类型”,这里我们使用splitParts属性去实现。
  • 同一组的数据应该是连续的,否则的话就要把不连续的数据扔到一个新的组去。

假设有一个数组[1, 2, 'a1c', 'a2c', 6, 8],元素1和2就应该被分配到名为Number的组去,a1c和a2c则会被分配到名为ac的组里面,而6和8则会被另外分配到名为Number1的新组里面去,最后结果如下:

{
 'Number': [{
 realValue: '1',
 ...
 }, {
 realValue: '2',
 ...
 }],
 'ac': [{
 realValue: 'a1c',
 ...
 }, {
 realValue: 'a2c',
 ...
 }],
 'Number1': [{
 realValue: '6',
 ...
 }, {
 realValue: '8',
 ...
 }]
}

代码请戳:classifier.js

通过上述步骤,我们成功把数据进行分组,组与组之间的元素并不会相互干扰。接下来我们需要实现一个专门做“线性回归”的方法,有了这个方法我们才能对数据进行“预测”。

Linear regression

“线性回归”是一个数学理论,详情请自己google之,这里我直接使用线性回归的二元一次公式去求得回归直线的斜率:

y = ax + b

a = ∑(x−x')(y−y') / ∑(x−x')(x−x')

其中x'是所有点x坐标的平均数,同样的,y'是所有点y坐标的平均数。

代码请戳:linearRegression.js

通过这条公式,我们可以轻易得到数组[1, 3]的斜率和偏移量为{ a: 2, b:1 },然后就可以知道以后的数据走向将会是[5, 7, 9, ...]。

这就是整一个“智能填充”的核心原理,接下来我们就可以依靠这个原理去实现数据的预测了。

Predictor

借助线性回归的力量,我们可以通过设置预测的次数,挨个挨个地对每一个分组数据进行预测,然后再把它们组合到一起形成一个新的结果数组。

以上文Classifier中的分组数据为例,对它预测一次,结果如下:

{
 'Number': [{
 realValue: '1',
 index: 0,
 ...
 }, {
 realValue: '2',
 index: 1,
 ...
 }, {
 realValue: '3',
 index: 6,
 ...
 }, {
 realValue: '4',
 index: 7,
 ...
 }],
 'ac': [{
 realValue: 'a1c',
 index: 2,
 ...
 }, {
 realValue: 'a2c',
 index: 3,
 ...
 }, {
 realValue: 'a3c',
 index: 8,
 ...
 }, {
 realValue: 'a4c',
 index: 9,
 ...
 }],
 'Number1': [{
 realValue: '6',
 index: 4,
 ...
 }, {
 realValue: '8',
 index: 5
 ...
 }, {
 realValue: '10',
 index: 10,
 ...
 }, {
 realValue: '12',
 index: 11
 ...
 }]
}

代码请戳:predictor.js

由于我们知道每一个数据的下标,所以我们可以简单又准确地把它们放到正确的位置去,最后输出如下:

[1, 2, 'a1c', 'a2c', 6, 8, 3, 4, 'a3c', 'a4c', 10, 12]

接下来我们可以来看看测试用例对比Excel表现:

利用JS实现一个同Excel表现的智能填充算法

More

当前的smart-predictor仍然不够“smart”,它只能预测自然数字,或者自然数字与字符串的结合,但仍然不支持对日期格式,字母列表等数据的预测。如果各位读者有兴趣,也非常欢迎大家来贡献脑洞,让smart-predicotr变得更加智能。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery的实现原理的模拟代码 -1 核心部分
Aug 01 Javascript
各浏览器对link标签onload/onreadystatechange事件支持的差异分析
Apr 27 Javascript
使用jQuery Ajax功能时需要注意的一个问题(内存溢出)
May 30 Javascript
js加载之使用DOM方法动态加载Javascript文件
Nov 08 Javascript
Yarn的安装与使用详细介绍
Oct 25 Javascript
关于Vue.js一些问题和思考学习笔记(1)
Dec 02 Javascript
JS实现简单抖动效果
Jun 01 Javascript
bootstrap基本配置_动力节点Java学院整理
Jul 14 Javascript
深入Vue-Router路由嵌套理解
Aug 13 Javascript
如何检查一个对象是否为空
Apr 11 Javascript
你不可不知的Vue.js列表渲染详解
Oct 01 Javascript
vue实现简单学生信息管理
May 30 Javascript
Vue自定义弹窗指令的实现代码
Aug 13 #Javascript
深入Vue-Router路由嵌套理解
Aug 13 #Javascript
AngularJS与后端php的数据交互方法
Aug 13 #Javascript
Vue Promise的axios请求封装详解
Aug 13 #Javascript
Angular6封装http请求的步骤详解
Aug 13 #Javascript
解决angularjs中同步执行http请求的方法
Aug 13 #Javascript
解决angularjs前后端分离调用接口传递中文时中文乱码的问题
Aug 13 #Javascript
You might like
腾讯QQ php程序员面试题目整理
2010/06/08 PHP
php操作mysql数据库的基本类代码
2014/02/25 PHP
微信公众号开发之通过接口删除菜单
2017/02/20 PHP
php实现的中秋博饼游戏之掷骰子并输出结果功能详解
2017/11/06 PHP
PHP实现一维数组与二维数组去重功能示例
2018/05/24 PHP
php的lavarel框架中join和orWhere的用法
2020/12/28 PHP
javascript innerText和innerHtml应用
2010/01/28 Javascript
让IE6支持min-width和max-width的方法
2010/06/25 Javascript
javascript 获取图片尺寸及放大图片
2013/09/04 Javascript
js点击事件链接的问题解决
2014/04/25 Javascript
基于javascript实现文字无缝滚动效果
2016/03/22 Javascript
Bootstrap每天必学之警告框插件
2016/04/26 Javascript
浅谈JavaScript中变量和函数声明的提升
2016/08/09 Javascript
JavaScript排序算法动画演示效果的实现方法
2016/10/18 Javascript
详解使用vue实现tab 切换操作
2017/07/03 Javascript
jQuery实现获取选中复选框的值实例详解
2018/06/28 jQuery
Nuxt.js开启SSR渲染的教程详解
2018/11/30 Javascript
vue element-ui el-date-picker限制选择时间为当天之前的代码
2019/11/07 Javascript
vue仿携程轮播图效果(滑动轮播,下方高度自适应)
2021/02/11 Vue.js
[52:37]完美世界DOTA2联赛循环赛 Forest vs DM BO2第一场 10.29
2020/10/29 DOTA
python的numpy模块安装不成功简单解决方法总结
2017/12/23 Python
Python实现连接postgresql数据库的方法分析
2017/12/27 Python
Tensorflow 利用tf.contrib.learn建立输入函数的方法
2018/02/08 Python
python实现五子棋游戏
2019/06/18 Python
关于Python3 类方法、静态方法新解
2019/08/30 Python
python网络爬虫 CrawlSpider使用详解
2019/09/27 Python
python 队列基本定义与使用方法【初始化、赋值、判断等】
2019/10/24 Python
详解基于canvas的视频遮罩插件
2018/01/04 HTML / CSS
Expedia意大利旅游网站:酒店、机票和租车预订
2017/10/30 全球购物
给定一个时间点,希望得到其他时间点
2013/11/07 面试题
工作表现自我评价
2014/02/08 职场文书
党的群众路线教育实践活动批评与自我批评
2014/02/16 职场文书
五月的鲜花活动方案
2014/08/21 职场文书
2014年党员自我评价材料
2014/09/22 职场文书
体育活动总结
2015/02/04 职场文书
Python天气语音播报小助手
2021/09/25 Python