Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Erlang Elixir:Mnesia:更新元素中的一组值的最简洁的方法是什么? 问题_Erlang_Elixir_Mnesia - Fatal编程技术网

Erlang Elixir:Mnesia:更新元素中的一组值的最简洁的方法是什么? 问题

Erlang Elixir:Mnesia:更新元素中的一组值的最简洁的方法是什么? 问题,erlang,elixir,mnesia,Erlang,Elixir,Mnesia,在学习使用健忘症和长生不老药时,我创建了一个具有多种功能(如读、写…)的表格。其中之一是更新一组字段(大小从1到count-1),而不更改其余数据,并将mnesia事务中的逻辑限制到最小 在我的搜索过程中,我碰巧发现了这个:虽然(代码如下)。这是同样的问题,但对二郎来说,不是长生不老药 代码 据我所知,它在Erlang中工作,因为read返回一个元组,该元组直接设置在记录中,这允许我们在写入操作中按命名保存特定数据 更新a(选项卡、键、值)-> 乐趣()-> [P] =mnesia:read({

在学习使用健忘症和长生不老药时,我创建了一个具有多种功能(如读、写…)的表格。其中之一是更新一组字段(大小从1到count-1),而不更改其余数据,并将mnesia事务中的逻辑限制到最小

在我的搜索过程中,我碰巧发现了这个:虽然(代码如下)。这是同样的问题,但对二郎来说,不是长生不老药

代码 据我所知,它在Erlang中工作,因为read返回一个元组,该元组直接设置在记录中,这允许我们在写入操作中按命名保存特定数据

更新a(选项卡、键、值)->
乐趣()->
[P] =mnesia:read({Tab,Key}),
mnesia:write(P#pixel{a=Value})
结束。
其中,对于Elixir,即使存在记录,它也只是一个元组,您只能在其中更改索引中的数据,并将完整元组返回给write操作

Table: {table_name, id, data1, data2, data3, data4}
changes = [{2, new_val_for_data1}, {4, new_val_for_data3}]

def handle_call({:update_and_read, table, {id, changes}}, _, state) do
  {:atomic, new_object} =
    :mnesia.transaction(fn ->
      object =
        :mnesia.wread({table, id})
        |> List.first()

      ret =
        Enum.reduce(changes, object, fn {index, value}, acc ->
          acc |> Tuple.delete_at(index) |> Tuple.insert_at(index, value)
        end)

      :mnesia.write(object)
      ret
    end)

  {:reply, {:ok, new_object}, state}
end
问题: 在Elixir中是否可以使用更短的函数(理想情况下,可以使用像Erlang中一样的两行)?

好的,您可以使用一些初步步骤(比如在应用程序中定义记录)

defmodule-Pixel-do
要求记录
Record.defrecord(:table_name,id:nil,data1:nil,data2:nil)
结束
在要更新表的模块中

import Pixel

def handle_call({:update_and_read, table, {id, changes}}, _, state) do
  # changes = [data2: new_val_for_data1, ...]
  {:atomic, result} =
    :mnesia.transaction(fn ->
      case :mnesia.wread({table, id}) do
        [object] -> 
          :mnesia.write(pixel(object, changes))
          {:ok, object}
        [] -> :error
      end
    end)

  {:reply, result, state}
end

另一种可能性是通过

changes=%{2=>new_val_for_data1,4=>new_val_for_data3}
对象
|>Tuple.to_list()
|>带有_索引()的枚举
|>map(fn{value,idx}->map.get(changes,idx,value)end)
|>List.to_tuple()

另一种可能是声明一个宏,该宏接受一个元组(表示表行)和一个
{idx,new_value}
元组列表,并在适当的位置更改相应的元素