如何合并相邻小多边形为大多边形?Elixir实现求助
嘿,我来帮你解决这个相邻多边形合并的问题!你想要把那些x连续、同高同y的小矩形合并成大的,用Elixir实现对吧?我之前也处理过类似需求,给你一个可行的方案:
首先咱们得明确合并规则:只有当两个矩形的y和height完全相同,并且后一个矩形的x刚好等于前一个的x + width时,才能把它们合并成一个新矩形——新矩形的x取前一个的x,width是两者宽度之和,y和height保持不变。
接下来看具体实现步骤:
- 先排序:确保多边形列表按
x坐标从小到大排列,否则乱序的元素会导致合并逻辑出错。 - 用
Enum.reduce遍历合并:遍历排序后的列表,每次和结果列表的最后一个元素比对,符合条件就合并,不符合就直接加入结果。
直接上代码示例:
# 你的原始多边形列表 polygons = [ %{height: 32, width: 32, x: 0, y: 0}, %{height: 32, width: 32, x: 32, y: 0}, %{height: 32, width: 32, x: 64, y: 0}, %{height: 32, width: 32, x: 256, y: 0}, %{height: 32, width: 32, x: 288, y: 0} ] # 第一步:按x坐标排序,确保顺序正确 sorted_polygons = Enum.sort_by(polygons, & &1.x) # 第二步:遍历合并相邻符合条件的多边形 merged_polygons = Enum.reduce(sorted_polygons, [], fn current, acc -> case acc do # 如果结果列表为空,直接加入当前元素 [] -> [current] [last | rest] -> # 检查是否满足合并条件 if last.y == current.y && last.height == current.height && (last.x + last.width) == current.x do # 合并:更新最后一个元素的宽度 [Map.merge(last, %{width: last.width + current.width}) | rest] else # 不满足条件,把当前元素加入结果列表头部 [current | acc] end end end) # 因为我们是往列表头部加元素,最后需要反转回正确顺序 |> Enum.reverse() # 输出结果就是你想要的: # [ # %{height: 32, width: 96, x: 0, y: 0}, # %{height: 32, width: 64, x: 256, y: 0} # ]
至于你提到的Enum.reduce_while,它更适合遍历过程中需要提前终止的场景,而咱们这个需求需要遍历完所有元素才能完成合并,所以用普通的Enum.reduce会更直接。如果一定要用reduce_while,虽然也能实现,但会多一些没必要的逻辑,不如上面的方案简洁。
另外,这个方案还能自动区分不同y或height的多边形,它们会被当成独立组,不会被错误合并,符合常规的合并逻辑。
内容的提问来源于stack exchange,提问作者Catharz
相关产品推荐
相关产品推荐

