计算地图列表中的平均秒数 Elixir

问题描述 投票:0回答:1

我有这个样本数据

[
%{  check_in_time: 60,
    imaging_time: 180,
    lab_time: 120,
    vital_time: 60,
    pharmacy_time: 100
},
%{
    check_in_time: 20,
    imaging_time: 380,
    lab_time: 10,
    vital_time: 60,
    pharmacy_time: 200
}
]

所有这些实体都以秒为单位显示时间,我想在这里实现的是:

计算这些时间的平均值,例如每个条目的呈现、患者详细信息以及患者在医院花费的时间,但现在我需要计算这些时间的总平均值,以显示患者的平均等待时间考虑所有患者的详细信息。

我做了什么。

    items
    |> Enum.reduce(
      %{
        check_in_time: 0,
        imaging_time: 0,
        lab_time: 0,
        pharmacy_time: 0,
        vital_time: 0
      },
      fn %{
           check_in_time: check_in_time,
           imaging_time: imaging_time,
           lab_time: lab_time,
           pharmacy_time: pharmacy_time,
           vital_time: vital_time
         },
         acc ->
        %{
          check_in_time: acc.check_in_time + check_in_time,
          imaging_time: acc.imaging_time + imaging_time,
          lab_time: acc.lab_time + lab_time,
          pharmacy_time: acc.pharmacy_time + pharmacy_time,
          vital_time: acc.vital_time + vital_time
        }
      end
    )
    |> sum_average()
  end

  defp sum_average(%{
         check_in_time: check_in_time,
         imaging_time: imaging_time,
         lab_time: lab_time,
         pharmacy_time: pharmacy_time,
         vital_time: vital_time
       }) do
    (check_in_time + imaging_time + lab_time + pharmacy_time + vital_time) / 5
  end

我做了一些研发,发现这不是正确的方法。请指导我使用上述数据计算平均时间值(以秒为单位)的正确方法。 PS:这些键的值也可以为零。

任何帮助都会很棒,谢谢。

更新:预期的公式和结果是。

    (60 + 20) / 2 (number of values) = 40
    (180 + 380) / 2 = 280
    (120 + 10) / 2 = 65
    (60 + 60) / 2 = 60
    (100 + 200) / 2 = 150

    (40 + 280 + 65 + 60 + 150) / 5 (number of values) = 119
elixir
1个回答
0
投票

下面的代码只是手动执行reduce(),以便在列表的最后一次迭代时,即当列表为空时,代码可以计算平均值:

defmodule My do
  def items do
    [
      %{  check_in_time: 60,
          imaging_time: 180,
          lab_time: 120,
          vital_time: 60,
          pharmacy_time: 100
      },
      %{
          check_in_time: 20,
          imaging_time: 380,
          lab_time: 10,
          vital_time: 60,
          pharmacy_time: 200
      }
    ]
  end
  
  //Public interface:
  def get_average(patients) do
    get_average(patients, [0,0,0,0,0,0])
  end 

  //Private helper function:
  defp get_average([], [cit, it, lt, pt, vt, count]) do
    patients_avg = (cit + it + lt + pt + vt)/count
    _category_avg = patients_avg/5
  end
  defp get_average([%{
    check_in_time: check_in_time,
    imaging_time: imaging_time,
    lab_time: lab_time,
    vital_time: vital_time,
    pharmacy_time: pharmacy_time} | patients], 
    [cit, it, lt, vt, pt, count] ) do

      get_average(patients, 
        [
          cit + if is_nil(check_in_time) do 0 else check_in_time end,
          it + if is_nil(imaging_time) do 0 else imaging_time end,
          lt + if is_nil(lab_time) do 0 else lab_time end,
          vt + if is_nil(vital_time) do 0 else vital_time end,
          pt + if is_nil(pharmacy_time) do 0 else pharmacy_time end,
          count + 1
        ]
      ) 
  end
end

在 iex 中:

/elixir_programs% iex a.ex
Erlang/OTP 24 [erts-12.3.2] [source] [64-bit] [smp:8:8] [ds:8:8:10] [async-threads:1]

Interactive Elixir (1.14.4) - press Ctrl+C to exit (type h() ENTER for help)


iex(1)> items = My.items()
[
  %{
    check_in_time: 60,
    imaging_time: 180,
    lab_time: 120,
    pharmacy_time: 100,
    vital_time: 60
  },
  %{
    check_in_time: 20,
    imaging_time: 380,
    lab_time: 10,
    pharmacy_time: 200,
    vital_time: 60
  }
]
iex(2)> My.get_average(items)
119.0

if is_nil()
语句可以更改为更短但更神秘的:

      cit + (check_in_time || 0),
      it + (imaging_time || 0),
      lt + (lab_time || 0),
      vt + (vital_time || 0),
      pt + (pharmacy_time || 0),
© www.soinside.com 2019 - 2024. All rights reserved.