Как я могу отобразить объект, если есть дублированное значение? - PullRequest
0 голосов
/ 03 мая 2018

У меня есть два списка, list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John}] и list_b = [%{id: nil, name: "Jack"}]

Чего я хочу добиться, так это то, что, сравнивая два списка, если есть дублированное имя, добавьте поле status: true, если нет, добавьте поле status: false.

Итак, ожидаемый результат - combined_list = [%{id: 1, name: "Jack", status: true}, %{id: 2, name: "John, status: false}]

Чтобы достичь цели, я зацикливаю два списка и объединяю результаты.

list_status_true =
for object <- list_a do
  found =      
    Enum.find(
      list_b,
        fn(x) ->
          x.name == object.name 
        end
      )

  if !is_nil(found) do
    %{
      id: object.id,
      name: object.name,
      status: true
    }
  end 
end

list_status_false =
for object <- list_b do
  found =      
    Enum.find(
      list_a,
        fn(x) ->
          x.name == object.name 
        end
      )

  if is_nil(found) do
    %{
      id: object.id,
      name: object.name,
      status: false
    }
  end 
end

list_status_true ++ list_status_false

Но я думаю, что эту функцию можно упростить. Есть предложения?

Ответы [ 2 ]

0 голосов
/ 03 мая 2018

Практически то же решение, что и @Dogbert, но без понимания:

list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John"}]
list_b = [%{id: nil, name: "Jack"}]

names = list_b |> Enum.map(& &1.name) |> Enum.uniq
Enum.map(list_a, fn %{name: name} = e ->
  Map.put(e, :status, name in names)
end)
#⇒ [%{id: 1, name: "Jack", status: true},
#   %{id: 2, name: "John", status: false}]
0 голосов
/ 03 мая 2018

Я бы собрал все имена в MapSet и затем один раз перебрал бы list_b, проверив, существует ли имя в MapSet:

list_a = [%{id: 1, name: "Jack"}, %{id: 2, name: "John"}]
list_b = [%{id: nil, name: "Jack"}]

names = for x <- list_b, into: MapSet.new, do: x.name

IO.inspect for x <- list_a, do: Map.put(x, :status, x.name in names)

Выход:

[%{id: 1, name: "Jack", status: true}, %{id: 2, name: "John", status: false}]
...