ExcelHome技术论坛

 找回密码
 免费注册

QQ登录

只需一步,快速开始

快捷登录

搜索
EH技术汇-专业的职场技能充电站 妙哉!函数段子手趣味讲函数 Excel服务器-会Excel,做管理系统 效率神器,一键搞定繁琐工作
HR薪酬管理数字化实战 Excel 2021函数公式学习大典 Excel数据透视表实战秘技 打造核心竞争力的职场宝典
让更多数据处理,一键完成 数据工作者的案头书 免费直播课集锦 ExcelHome出品 - VBA代码宝免费下载
用ChatGPT与VBA一键搞定Excel WPS表格从入门到精通 Excel VBA经典代码实践指南
12
返回列表 发新帖
楼主: 果子麦子

[求助] 求助,求教PowerQuery怎么把包含相同元素的数据分成同1组

[复制链接]

TA的精华主题

TA的得分主题

发表于 2023-10-29 19:46 | 显示全部楼层
本帖最后由 一江春水1688 于 2023-10-29 21:25 编辑

果然,可以直接上传图片

测试,上传图片需要审核吗?

测试,上传图片需要审核吗?




评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2023-10-30 08:12 | 显示全部楼层
一江春水1688 发表于 2023-10-29 19:34
厉害!
用了好多高级技巧!
js正在入门中,学习并初步解析:

是的,代码处理思路就是这样的,还可以稍微优化一下,少一些循环次数 image.png
  1. function 传播链() {
  2.         const sht = Worksheets("传播链")
  3.         const arr = sht.Range("B2:C7").Value2.map(v => [[v[0]], [v[1].split(/、/g)]])
  4.         const set = new Set()
  5.         const update = (x, i) => {
  6.                 if (!(x in arr)) return arr[x] = i                                                        // 标记索引
  7.                 let j = arr[x]                                                                                                // 之前数据的索引
  8.                 if (j == i || !(j in arr)) return                                                        // 是否已被处理
  9.                 arr[j].forEach((a, y) => a.forEach(v => arr[i][y].push(v)))        // 取得后面的时间序号和受感染者
  10.                 arr[i][1].forEach(xArr => xArr.forEach(a => arr[a] = i))        // 更新状态                               
  11.                 delete arr[j]                                                                                                // 清空之前的数据,做个标记
  12.         }
  13.         arr.reduceRight((_, v, i) => v[1].forEach(xArr => xArr.forEach(x => update(x, i))), null);        // 倒着来,逐行推导
  14.         const res = arr.reduce((res, v, i) => {
  15.                 res.push([v[0].join("、"), v[1].map(v => v.join("、")).join(";")])
  16.                 return res
  17.         }, [["时间序号","同一个传播链"]])
  18.         sht.Range("F6").Resize(res.length, 2).Value2 = res
  19. }
复制代码


评分

1

查看全部评分

TA的精华主题

TA的得分主题

发表于 2023-10-30 20:25 来自手机 | 显示全部楼层

TA的精华主题

TA的得分主题

发表于 2023-11-1 21:09 | 显示全部楼层
飞天篮球猪 发表于 2023-10-19 20:23
供参考。效率不高,只是解题,都是全表遍历。

方法1:List.Accumulate

学习大佬的精妙思路,并用wps js宏来实现。初学js,一个一个函数啃,发现这样学习的进度很快,感谢飞天篮球猪大佬提供的思路一。方法二,有空再学习研究。先贴图,代码稍后提供。

传播链求解代码.png

TA的精华主题

TA的得分主题

发表于 2023-11-1 21:11 | 显示全部楼层
飞天篮球猪 发表于 2023-10-19 20:23
供参考。效率不高,只是解题,都是全表遍历。

方法1:List.Accumulate

代码如下:

  1. function 同一传播链(){
  2.         /*思路:逐行扫描原始数据数组arr,并记录到数组s【初始值为空数组】,新扫描的是arr中的当前行c,用c查
  3.                 找上一次扫描记录的s,凡是匹配的项目都记录到数组a。然后,从s中删除a,使s只剩下之前未匹配的项目。
  4.                 再把已经匹配的a和c合并,并记录到数组v。最后,把v添加到更新后的s尾部,传递给下一次循环的s*/
  5.         const arr = Range("b2:c7").Value2;
  6.         acc = arr.reduce((s, c)=>{
  7.                 let a = [];  //在s中找c,记录到数组a, u[1]).includes(x)
  8.                 s.forEach((u,j) => c[1].split("、").some((x) => y = u[1].includes(x) && a.push(s[j])));
  9.                 a.forEach((x) => ((k = s.indexOf(x)) > -1) && s.splice(k, 1));  //s中排除a,并更新s
  10.                 let v = (a.length == 0) ? c : (  //逗号表达式
  11.                         a.push(c),
  12.                         (a[0].map((col, i) => a.map((row) => row[i]))).map(x => x.join(";"))
  13.                 );  //a与c合并,赋值到新数组v
  14.                 return s.push(v), s;  //逗号运算符,返回最后的表达式
  15.         },[]);
  16.         acc.unshift(["时间序号", "同一个传播链"]); //数组acc头部插入标题
  17.         Range("b10").Resize(acc.length,2).Value2=acc;
复制代码


您需要登录后才可以回帖 登录 | 免费注册

本版积分规则

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

GMT+8, 2024-12-26 15:04 , Processed in 0.037648 second(s), 8 queries , Gzip On, MemCache On.

Powered by Discuz! X3.4

© 1999-2023 Wooffice Inc.

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

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

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