You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elixir等函数式语言如何过滤嵌套子数组并保留外层结构

问题描述

当前使用Elixir开发,该解决思路同样适用于所有函数式语言。需求为处理可能嵌套JSON子数组的JSON数组,需要实现两类效果:

  • 筛选出子数组中符合特定值条件的元素
  • 若筛选后子数组中至少剩余1个元素,则保留对应的外层数组元素

示例

输入

decisions = [%{
  "name" => "Only for B",
  "chance" => 0,
  "modifiers" => [%{
    "position" => 0,
    "match" => "B",
    "weight" => 0
  },
  %{
    "position" => 0,
    "match" => "C",
    "weight" => 1
  }
]
}]

期望输出

移除所有weight字段不为0的元素,完整保留外层结构:

expected_result = [%{
  "name" => "Only for B",
  "chance" => 0,
  "modifiers" => [%{
    "position" => 0,
    "match" => "B",
    "weight" => 0
  }]
}]

实际错误输出

外层数组结构丢失,仅返回筛选后的子数组:

actual_result = [[%{
  "position" => 0,
  "match" => "B",
  "weight" => 0
}]]

问题原因

当前编写的代码如下:

def modifiers_with_certainty(decisions) do
  Enum.map(decisions, fn decision ->
    Enum.filter(decision["modifiers"], fn modifier ->
      modifier["weight"] == 0
    end)
  end)
end

现有代码的核心错误是:外层Enum.map直接返回了内层筛选后的modifiers子数组,没有把筛选结果塞回原外层decision的结构里,自然会丢失name、chance这些外层字段。如果外层直接换用Enum.filter也无法实现需求,因为filter只能决定当前元素留不留,没法修改元素内部的子数组内容。


解决方案

实现逻辑分两步:

  1. 对每个外层元素,先筛选内部的modifiers子数组,再将筛选后的子数组更新回原外层元素结构,保留其他所有字段
  2. 丢弃所有筛选后modifiers子数组为空的外层元素

可以用Enum.flat_map一次性遍历完成两个操作,代码如下:

def modifiers_with_certainty(decisions) do
  Enum.flat_map(decisions, fn decision ->
    # 先筛选内层子数组
    filtered_modifiers = Enum.filter(decision["modifiers"], &(&1["weight"] == 0))

    if Enum.empty?(filtered_modifiers) do
      # 子数组为空则丢弃该外层元素
      []
    else
      # 子数组非空则返回更新后的外层结构
      [%{decision | "modifiers" => filtered_modifiers}]
    end
  end)
end

如果更偏好分步的可读写法,也可以先map更新结构,再filter丢弃空元素,逻辑完全等价:

def modifiers_with_certainty(decisions) do
  decisions
  |> Enum.map(fn decision ->
    filtered_modifiers = Enum.filter(decision["modifiers"], &(&1["weight"] == 0))
    %{decision | "modifiers" => filtered_modifiers}
  end)
  |> Enum.filter(&(length(&1["modifiers"]) > 0))
end

内容的提问来源于stack exchange,提问作者Jules

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 04:27:25