Elixir Today: 특정 필드를 통해 맵 목록 결합
                                            
                                                
                                                
                                                
                                                
                                                
                                                 17691 단어  webdevprogrammingelixirdata
                    
참조
references
소개
최근에
How to combine a list of map via specific field 에 대한 비슷한 질문에 대해 작업했습니다.나는 엘릭서 포럼을 보았고 기꺼이 무언가를 찾았습니다. 답변 중 하나가
Enum.group_by + Enum.map 을 사용하는 것을 보았습니다.내 호기심을 감안할 때
How can I come up with a solution using Enum.reduce ?호기심 발동
그래서
Enum.reduce를 사용하여 운동을 시작했습니다.
 @list [
    %{id: 1, list: [1]},
    %{id: 1, list: [2]},
    %{id: 2, list: [1]},
    %{id: 3, list: [1]},
    %{id: 1, list: [3, 4, 5]},
    %{id: 2, list: [2, 3]},
    %{id: 3, list: [2, 3, 4, 5]},
    %{id: 4, list: [2, 3, 4, 5]},
    %{id: 4, list: [1]}
  ]
    @list
    |> Enum.reverse()
    |> Enum.reduce(%{}, fn %{id: id, list: _list} = f, acc ->
      case acc do
        %{^id => existing} -> Map.put(acc, id, [f | existing])
        %{} -> Map.put(acc, id, [f])
      end
    end)
    |> Enum.map(fn {id, list} -> %{id: id, list: Enum.flat_map(list, & &1.list)} end)
Enum.map를 사용하여 데이터를 변환합니다. 벤치마킹!
group_by 와 reduce 를 사용한 결과를 비교하기 시작했습니다. 이를 위해 Benchee 을 사용했습니다.설치하려면 종속 항목에 benchee를 추가하세요.
{:benchee, "~> 1.0", only: :dev}
주어진 설정
 @list [
    %{id: 1, list: [1]},
    %{id: 1, list: [2]},
    %{id: 2, list: [1]},
    %{id: 3, list: [1]},
    %{id: 1, list: [3, 4, 5]},
    %{id: 2, list: [2, 3]},
    %{id: 3, list: [2, 3, 4, 5]},
    %{id: 4, list: [2, 3, 4, 5]},
    %{id: 4, list: [1]}
  ]
def groupby(list) do
    Enum.group_by(list, & &1.id)
    |> Enum.map(fn {id, list} -> %{id: id, list: Enum.flat_map(list, & &1.list)} end)
end
def reduce(list) do
    list
    |> Enum.reverse()
    |> Enum.reduce(%{}, fn %{id: id, list: _list} = f, acc ->
      case acc do
        %{^id => existing} -> Map.put(acc, id, [f | existing])
        %{} -> Map.put(acc, id, [f])
      end
    end)
    |> Enum.map(fn {id, list} -> %{id: id, list: Enum.flat_map(list, & &1.list)} end)
end
그런 다음 실행
Benchee.run(
   %{
        "groupby_enum_map" => fn -> PracticeElixir.groupby(@list) end,
        "reduce_enum_map" => fn -> PracticeElixir.reduce(@list) end
      },
      print: [fast_warning: false]
)
벤치마크 결과
내 개발 환경을 감안할 때 결과는 다음과 같습니다.
available_memory: "16 GB",
cpu_speed: "Intel(R) Core(TM) i9-9880H CPU @ 2.30GHz",
elixir: "1.12.3",
erlang: "24.0.6",
num_cores: 16,
os: :macOS
Benchmark suite executing with the following configuration:
warmup: 2 s
time: 5 s
memory time: 0 ns
reduction time: 0 ns
parallel: 1
inputs: none specified
Estimated total run time: 14 s
Benchmarking groupby_enum_map ...
Benchmarking reduce_enum_map ...
Name                       ips        average  deviation         median         99th %
reduce_enum_map         1.08 M        0.93 μs   ±208.21%        0.80 μs           5 μs
groupby_enum_map        0.97 M        1.03 μs   ±251.03%        0.90 μs           4 μs
Comparison:
reduce_enum_map         1.08 M
groupby_enum_map        0.97 M - 1.12x slower +0.109 μs
전체 구현을 볼 수 있습니다here!.
Happy Coding!
Reference
이 문제에 관하여(Elixir Today: 특정 필드를 통해 맵 목록 결합), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/paugramming/elixir-today-combining-a-list-of-map-via-specific-field-4a5j텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
                                
                                
                                
                                
                                
                                우수한 개발자 콘텐츠 발견에 전념
                                (Collection and Share based on the CC Protocol.)