ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 Excel Home精品图文教程库
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
300集Office 2010微视频教程 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
楼主: xx6000

[求助] 如何用js数组reduce方法实现统计

[复制链接]

TA的精华主题

TA的得分主题

发表于 2024-5-31 22:33 | 显示全部楼层
一江春水1688 发表于 2024-5-31 21:50
dic[a] = dic[a] || 0
等价于
if (!dic[a]) dic[a] = 0

正解,就是这个意思,后面是可以简写的,dic[a] ||= 0,但是能用||=,也就能用??=了,虽说在这里功能一样,但其中是用区别滴,||=,左边可以是0,空字符串,false值等一切转成布尔值为false的值,??=则是左边是null或者undefined,才会赋初值

评分

3

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-6-1 11:28 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
今铭昔 发表于 2024-5-31 22:33
正解,就是这个意思,后面是可以简写的,dic[a] ||= 0,但是能用||=,也就能用??=了,虽说在这里功能一样 ...

明白,谢谢大佬详解!
dic[a] ||= 0 和 dic[a] ??= 0,后者对 dic[a] 的赋值要求更加严格,

TA的精华主题

TA的得分主题

 楼主| 发表于 2024-6-1 19:15 | 显示全部楼层
再增加点难度,如果有一个天干数组(单一元素)和五行数组(多组五行元素),每个天干元素后面跟的是多个五行元素如何统计?比如天干[0]即“丁”后面跟随的是五行[0]里面的“水、木、水、木、土、火“6个数据,得出的第一个结果是丁后面出现的水2火1木2金0土1。依次类推。给出的模拟数据如下所示:
天干                        五行                                       
丁                        水        木        水        木        土        火
辛                        金        金        水        水        金        土
甲                        木        火        木        土        水        火
戊                        木        金        火        土        水        土
辛                        金        土        火        土        水        水
乙                        水        土        火        水        水        木
戊                        木        金        金        水        水        水
壬                        金        木        火        木        金        土
乙                        土        木        金        火        土        土
己                        水        火        金        木        火        木
壬                        火        水        土        金        土        火
丙                        火        火        火        水        火        土
己                        木        木        木        火        火        水
癸                        木        水        火        水        木        土
丙                        土        水        金        水        火        金
庚                        土        木        水        火        木        水
癸                        土        水        木        木        土        木
丁                        水        土        土        金        土        木
庚                        火        木        木        木        水        金
统计结果如下:
        水        火        木        金        土
甲        1        2        2                1
乙        3        2        2        1        4
丙        3        5        0        2        2
丁        3        1        3        1        4
戊        4        1        2        3        2
己        2        4        5        1        0
庚        3        2        5        1        1
辛        4        1        0        4        3
壬        1        3        2        3        3
癸        3        1        5        0        3

TA的精华主题

TA的得分主题

发表于 2024-6-2 07:20 | 显示全部楼层
xx6000 发表于 2024-6-1 19:15
再增加点难度,如果有一个天干数组(单一元素)和五行数组(多组五行元素),每个天干元素后面跟的是多个五 ...

image.png

天干五行计数By@今铭昔0602.zip

12.23 KB, 下载次数: 7

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-6-2 12:39 | 显示全部楼层

感谢大佬耐心指教,经过几天消化,初步明白了许多高级用法:

  1. function run0602(){
  2.         const dic = {}
  3.         const {map, forEach} = Array.prototype                                                        // 对象解构,取出数组原型对象里的两个成员函数
  4.         const res = map.call('\u0000甲乙丙丁戊己庚辛壬癸', s => dic[s]=[s])        // 生成二维数组并映射天干元素所对应的数组对象
  5.         forEach.call('水火木金土', s => res[0][s] = res[0].push(s) - 1)        // 添加五行并映射所对应的列索引
  6.         Range('A1:G19').Value2                                                                                        // 不过是多套了一层循环。。。。。。
  7.                 .forEach(([a, ...v]) => v.forEach(s => (dic[a][s = res[0][s]] ??= 0, dic[a])[s]++))
  8.         Range('I1').Resize(res.length, res[0].length).Value2 = res
  9. }
复制代码
①对象解构,可以使得之后的代码更加简约:
Array.prototype.map.call 简写为 map.call
Array.prototype.forEach.call 简写为 forEach.call


②第6行(至第7行)二重循环代码中,参数 ([a, ...v]),表示二维数组的某行(是个一维数组)的 a元素及剩余元素v,
③第4行代码,除了生成二维数组 res 和字典 dic ,还有一个非常重要的作用,res 的第1列跟dic的Values指向同一地址,当dic自加产生变化时也同样引起res同样变化
④偶然发现,"\u0000" 也可以写成 "\x00",前者对应unicode多字节字符,后者对应单字节ASC字符





评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-6-2 16:54 | 显示全部楼层
[广告] Excel易用宝 - 提升Excel的操作效率 · Excel / WPS表格插件       ★免费下载 ★       ★ 使用帮助

TA的精华主题

TA的得分主题

发表于 2024-6-2 21:00 | 显示全部楼层

大佬的代码,一看就明白原理,写得很精练,想得到大佬的代码,使用了ocr识别,再人工修正个别错误,反复核对了几遍。可是一运行,二重循环内循环就出错。不得已,只好重新写一遍,并把代码展开,以方便调试。代码如下:
  1. function test_wodewan(){
  2.     const [row,col]=['甲乙丙丁戊已庚辛王癸','水火木金土'];
  3.     const res = Array.from(row, (r, i) =>
  4.             [r, ...(i ? ''.padEnd(col.length) : col)]);
  5.         console.log(JSON.stringify(res, null, 4))
  6.     Range('A1:G19').Value2.forEach(([r, ...c]) => {
  7.             c.forEach((e) => {
  8.                     let i = row.indexOf(r);
  9.                     let j = col.indexOf(e);
  10.                     if(i == -1 || j == -1){
  11.                             console.log();//此处中断,查看 i, j
  12.                     }
  13.                     res[i][j + 1]++  //这里出错
  14.             })
  15.     })
  16. }
复制代码
结果,发现,代码绝大部分没写错,竟错在第2行的初始化变量处:
'甲乙丙丁戊已庚辛王癸',前面少了个空格
②""和”王“也错了,表面看起来似乎一样(视力有问题啊)

最后,还原大佬的代码如下:
  1. function run_wodewan(){
  2.     const [row,col]=[' 甲乙丙丁戊己庚辛壬癸','水火木金土'];
  3.     const res = Array.from(row, (r, i) =>
  4.         [r, ...(i ? ''.padEnd(col.length) : col)]);
  5.     Range("A1:G19").Value2.forEach(([r,...c]) =>
  6.         c.forEach(e => res[row.indexOf(r)][col.indexOf(e)+1]++));
  7.     Range('I1').Resize(res.length, res[0].length).Value2 = res;
  8. }
复制代码
在此记录一下,警醒自己



TA的精华主题

TA的得分主题

发表于 2024-6-3 10:40 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
就用一招。。。。
360截图20240603104241428.jpg
360截图20240603104303426.jpg

工作簿1.zip

12.91 KB, 下载次数: 1

评分

2

查看全部评分

TA的精华主题

TA的得分主题

发表于 2024-6-3 13:15 | 显示全部楼层
消化了几天大佬的代码,来一段代码练练手:
  1. function test(){
  2.     const [row,col]=['\x00甲乙丙丁戊己庚辛壬癸','水火木金土']
  3.     const res=[...row].map((x,i)=>[x,...(i?Array(col.length):col)])//生成初始二维数组
  4.     Range("a1:g19").Value2.forEach(([y,...x]) => x.forEach((z,i) => {
  5.             i=row.indexOf(y),z=col.indexOf(z)+1,res[i][z]??=0,res[i][z]++}))//巧借参数z,i当临时变量用
  6.     Range('I1').Resize(res.length, res[0].length).Value2 = res
  7. }
复制代码

TA的精华主题

TA的得分主题

发表于 2024-6-3 14:44 | 显示全部楼层
[广告] VBA代码宝 - VBA编程加强工具 · VBA代码随查随用  · 内置多项VBA编程加强工具       ★ 免费下载 ★      ★使用手册
练练手,再换一种写法:
  1. function test(){
  2.     const [row,col]=['\x00甲乙丙丁戊己庚辛壬癸','水火木金土']
  3.     const res=[...row].map((x,i)=>[x,...(i?Array(col.length).fill(null):col)])
  4.     Range("a1:g19").Value2.forEach(([y,...x])=>
  5.         x.forEach((z,i)=>{res[row.indexOf(y)][col.indexOf(z)+1]++}))
  6.     Range('I1').Resize(res.length, res[0].length).Value2 = res
  7. }
复制代码

这段代码的第3行,二维数组初始化时,空白元素,填充的是null元素,是可以自加的,我的上一段代码表面上填充了null,实际上填充的是undefined,无法自加。
当变量 x 的值是空格符或null时,变量 x++ ,会把空格或null先转换为0,自加后就等于1了。这是我调试时发现的,后来在MDN网站找到答案。
当变量x的值是undefined时,x++,结果是NaN,因此要先判断再自加,即:
x ?? =0, x++
您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

关闭

最新热点上一条 /1 下一条

手机版|关于我们|联系我们|ExcelHome

GMT+8, 2024-6-18 19:23 , Processed in 0.040740 second(s), 10 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

沪公网安备 31011702000001号 沪ICP备11019229号-2

本论坛言论纯属发表者个人意见,任何违反国家相关法律的言论,本站将协助国家相关部门追究发言者责任!     本站特聘法律顾问:李志群律师

快速回复 返回顶部 返回列表