Elixir - increment a field value in Ecto map

I am getting two maps to a function.

Map1 is a list of maps

Map2 is a single map

I have to Enum.each this Map1 and marge with Map2(Which is static) and then insert in to database

This is working fine for me

Map example before inserting in to Database

%{
  api_id: 1,
  category_id: 2,
  content_url: "SeC9UPNoND8",
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "4wb8AYt3ECM",
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "2TSdkYkapo8",
  sub_category_id: 1
}
  def store_in_db(Map1, Map2) do
    
    Enum.each(Map1, fn(data) -> 
      Map.merge(data, Map2)
        |> Contents.create_content
      end)

  end

But now i got one new field to be added which is an just an increment $i++. which must be stored in priority field. For example in Map1 list i have got 3 maps. So i need below output

%{
  api_id: 1,
  category_id: 2,
  content_url: "SeC9UPNoND8",
  priority: 1,
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "4wb8AYt3ECM",
  priority: 2,
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "2TSdkYkapo8",
  priority: 3,
  sub_category_id: 1
}

I have done this

  def store_in_db(Map1, Map2) do
    
    Enum.each(Map1, fn(data) -> 
      Map.merge(data, Map2)
        |> Map.merge(%{priority: 1})
        |> Contents.create_content
      end)

  end

In that i want to increment priority value. Can someone give me insight on how to achieve this

You might use Enum.with_index for this.

I checked Enum.with_index but I am unable to find any example with Enum.each and Enum.index.

Not tested, but something like this…

BTW Did You name your variables from Erlang? It’s usual to start with lowercase in Elixir.

  def store_in_db(m1, m2) do
    m1
    |> Enum.with_index()
    |> Enum.each(fn({data, index}) -> 
      Map.merge(data, m2)
        |> Map.merge(%{priority: index})
        |> Contents.create_content
      end)
  end
2 Likes

Wow super it is working. But its index starting from zero. Like this

%{
  api_id: 1,
  category_id: 2,
  content_url: "SeC9UPNoND8",
  priority: 0,
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "4wb8AYt3ECM",
  priority: 1,
  sub_category_id: 1
}
%{
  api_id: 1,
  category_id: 2,
  content_url: "2TSdkYkapo8",
  priority: 2,
  sub_category_id: 1
}

I want index to start from 1.
So i did a small hack like below

    datas
        |> Enum.with_index()
        |> Enum.each(fn({data, index}) 
            -> Map.merge(data, add_info) 
                  |> Map.merge(%{priority: index+1})
                  |> IO.inspect
        #|> Contents.create_content
      end)

Is there any better way to achieve that?

You could also specify the offset as a parameter…

|> Enum.with_index(1)
3 Likes

Thank you. It works.