The general problem is, when used with the update operations, both find/1 and filter/1 would have to build the original shape back, instead of simply returning a list (which is what the Enum functions do). It could be done for maps and filter, but I am not quite sure about find. Also, we need to be careful to not promote traversals in maps (by using find) instead of doing a per key operation.
On Mon, Jul 1, 2024 at 8:27 AM Philip Munksgaard <pmunksga...@gmail.com> wrote: > Hi, > > I'm a frequent user of the Access module, and I'm excited about the recent > addition of Access.find/1 to support some use-cases I've had to work my way > around in the past. However, now that I have it, the first thing I wanted > to do actually applied to a map. > > For context, I'm working with Ecto changesets in a Phoenix LiveView > application. I'm working with a `Foo` schema that has an assoc containing a > number of uploaded files. Whenever I edit a Foo, I want to be able to > upload a new file, but only one at a time. I also want to be able to edit > the attached descriptions to each of the files that are already uploaded. I > have written some logic that only shows one live_file_input at a time, and > I have written the following `save` function (following the pattern in the > standard phx.gen.live templates): > > ```elixir > defp save(socket, :edit, foo_params) do > uploaded_entries_params = consume_uploaded_entries(socket, :file, > &upload_consumer/2) > > foo_params = > case uploaded_entries_params do > [] -> > foo_params > > [upload_params] -> > update_in( > foo_params, > ["foo_files", Access.find(&is_nil(&1["file_id"])), "file"], > &Map.merge(&1, upload_params) > ) > end > > case Foos.update_foo(socket.assigns.foo, foo_params) do > {:ok, foo} -> > {:noreply, push_patch(socket, to: socket.assigns.patch)} > > {:error, %Ecto.Changeset{} = changeset} -> > {:noreply, assign_form(socket, changeset)} > end > end > ``` > > The interesting bit is the `update_in` call, which takes the params > generated by my `upload_consumer` and merges it with the params coming from > the form submission. Unfortunately, this doesn't work, since > `foo_params["foo_files"]` is a map of the form: `%{"0" => %{ ... }, ...}` > > I was a bit surprised to find that Access.find/1 doesn't work with maps, > but then I remembered that the same is true for Access.filter/1. My (very) > cursory look at the implementation suggests that both of those are using > Enum-functions, which _do_ in fact support maps, so I am wondering why that > is not the case for the Access-functions? Would there be any interest in > adding support for maps in Access.find/1 and Access.filter/1? > > Best regards > Philip > > -- > You received this message because you are subscribed to the Google Groups > "elixir-lang-core" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to elixir-lang-core+unsubscr...@googlegroups.com. > To view this discussion on the web visit > https://groups.google.com/d/msgid/elixir-lang-core/d29a0d69-db72-4d2d-814e-5809c4f8da6f%40app.fastmail.com > . > -- You received this message because you are subscribed to the Google Groups "elixir-lang-core" group. To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-core+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/elixir-lang-core/CAGnRm4LuS16x9hhTLneJjEuJO5aWUXhjY4QU_sxyLVad%3Ddus7Q%40mail.gmail.com.