今天,WPS的JS宏战胜了VBA
话不多说,今天被人问了一个简单的问题:已知有12个人,每4人一组,分成3组,如何将所有可能的分组列到Excel表里?
高中数学痛击我.jpg
好吧,很容易知道共有C(12,4)*C(8,4)*C(4,4)/A(3,3)共5775种可能性。
自然而然,我们会去EH论坛找大佬求排列组合的VBA代码,然后脑子就短路了,这VBA写的递归也太。。。占脑子的缓存了,自己写的时候顾头不顾腚,怕不是得了老年痴呆。
幸好,我们用过python的itertools,知道有排列组合库这种巨人的肩膀,另外,前两天有个重大发现,就是WPS的JS宏可以直接用npm里很多的js模块,赶快去搜,找到了这个generatorics/generatorics.js at master · acarl005/generatorics · GitHub
很好,只要把js代码粘贴到WPS宏编辑器的一个模块里,然后点击工具-选项-编译,去掉禁止全局变量的两个选项,一般的排列组合问题就变成一个for循环的事了。
比如,有6个公司,每个公司4个部门,要从中选出来自不同公司、不同部门的4人,列出所有可能的组合,就可以这样:

简单说就是先对行的“组合”循环,再对列的“排列”循环即可。
书归正传,由于开头的那个问题是组合嵌套组合,所以还是躲不开要写递归啊,通过学习这个排列组合模块的写法,发现G.combination是一个递归的生成器,所以我们在外面再套一层递归的生成器即可,就像这样:

5775行,50毫秒出结果,这一刻我觉得JS宏完胜,当然标题是有点震惊那味了,但仅凭可以使用npm里的大量的js模块,JS宏觉得值得一用。
最后推荐一些有用的模块:
6tail的lunar.js,丰富又完善的农历库
fastest-levenshtein,编辑距离计算库,用来模糊匹配不规范的公司简写
lodash,可以拆出功能来用
ramda等等不用多说