如何实现包含重复元素的不等长列表差异计算?
Q语言实现带重复元素的不等长列表差异计算
Q语言原生的except操作是基于集合的,会自动去重,无法保留重复元素的差异(比如示例中l1里的两个4,l2里只有一个,原生except会把4全部排除)。要得到包含重复元素的正确差异结果,可以通过以下两种方式实现:
方法一:基于元素频次统计
这种方法通过统计两个列表中各元素的出现次数,计算l1中元素超出l2的次数,再展开得到结果,效率较高,适合处理大列表。
dupExcept:{[a;b] // 统计列表中每个元素的出现次数 cntA:count each group a; cntB:count each group b; // 计算l1元素比l2多出现的次数(不足0的取0) diffCnt:@[cntA;key cntB;-;cntB] where @[cntA;key cntB;-;cntB]>0; // 按频次重复元素并合并结果 raze {x#y} each flip (value diffCnt;key diffCnt) }
测试示例:
q)l1:1 1 2 3 3 4 4 5 6 7 q)l2:1 1 2 4 5 6 q)dupExcept[l1;l2] 3 3 4 7
方法二:逐个移除匹配元素
这种方法逻辑直观,遍历l2中的每个元素,从l1的副本中逐个移除第一个匹配项,剩下的就是差异。适合小列表场景,大列表下性能不如方法一。
dupExcept2:{[a;b] res:a; // 遍历l2元素,逐个从res中移除首个匹配项 {res:first res where res<>x;} each b; res }
测试示例:
q)dupExcept2[l1;l2] 3 3 4 7
内容的提问来源于stack exchange,提问作者Rajasekhar
相关产品推荐
相关产品推荐

