Julia 修改名称基于数组内容的对象

Julia 修改名称基于数组内容的对象,julia,Julia,我有一个两元素向量,它的元素只能是0或1。在本例中,假设x=[0,1]。假设还有四个对象y00、y01、y10、y11。我的目标是根据x的当前值更新相应的y(y01) 我知道我可以使用一系列if语句来实现这一点: if x == [0, 0] y00 += 1 elseif x == [0, 1] y01 += 1 elseif x == [1, 0] y10 += 1 elseif x == [1, 1] y11 += 1 end 然而,我知道这可以通过使用更

我有一个两元素向量,它的元素只能是0或1。在本例中,假设
x=[0,1]
。假设还有四个对象
y00、y01、y10、y11
。我的目标是根据
x
的当前值更新相应的
y
y01

我知道我可以使用一系列
if
语句来实现这一点:

if x == [0, 0]
    y00 += 1
elseif x == [0, 1]
    y01 += 1
elseif x == [1, 0]
    y10 += 1
elseif x == [1, 1]
    y11 += 1
end
然而,我知道这可以通过使用更简洁的方式来完成,尽管我不熟悉它的用法,也不知道如何使用。 我希望能够表达类似于
y{x[1]}{x[2]}+=1
(这显然是错误的);基本上,能够根据
x
的当前值参考和修改正确的
y
。 到目前为止,我已经能够调用正确的
y
对象的实际值(但我不能调用
y
对象本身)

eval(Symbol(string("y", x[1], x[2])))

如果我没有使用合适的术语,我很抱歉,但我希望我能说清楚

使用x作为数组Y的线性索引怎么样

x = reshape(1:4, 2, 2)
Y = zeros(4);
Y[ x[1,2] ] += 1

有一种更优雅的使用方法。您可以为
y
值定义一个通用类型,它的行为类似于一个矩阵(我假设
y
s代表什么?),并为您定义了很多东西:

julia> mutable struct Thing2 <: FieldMatrix{2, 2, Float64}
           y00::Float64
           y01::Float64
           y10::Float64
           y11::Float64
       end

julia> M = rand(Thing2)
2×2 Thing2 with indices SOneTo(2)×SOneTo(2):
 0.695919  0.624941 
 0.404213  0.0317816

julia> M.y00 += 1
1.6959194941562996

julia> M[1, 2] += 1
1.6249412302897646

julia> M * [2, 3]
2-element SArray{Tuple{2},Float64,1,2} with indices SOneTo(2):
 10.266662679181893 
  0.9037708026795666
julia>可变结构Thing2 M=rand(Thing2)
2×2东西2,指数为SOneTo(2)×SOneTo(2):
0.695919  0.624941 
0.404213  0.0317816
julia>M.y00+=1
1.6959194941562996
julia>M[1,2]+=1
1.6249412302897646
julia>M*[2,3]
二元SArray{Tuple{2},Float64,1,2},索引为SOneTo(2):
10.266662679181893
0.9037708026795666

(旁注:Julia索引从1开始,因此对
y
使用基于一的索引可能更为惯用。或者,使用具有自定义索引的数组类型,但这同样需要更多的工作。)

每当你发现自己用序列号命名变量时,你应该使用数组,这是一个巨大的危险信号。无需使用自定义静态数组或线性索引使其变得如此复杂-您只需将
y
制作成一个普通的旧2x2数组即可。直接的转变是:

y = zeros(2,2)
if x == [0, 0]
    y[1,1] += 1
elseif x == [0, 1]
    y[1,2] += 1
elseif x == [1, 0]
    y[2,1] += 1
elseif x == [1, 1]
    y[2,2] += 1
end
现在,您可以在这里看到一个模式,并通过使用
x
作为直接进入
y
的索引来简化它:

y[(x .+ 1)...] += 1

我在那里做了两件事:我在
x
的所有元素中添加一个元素,然后我将这些元素添加到索引表达式中,以便将它们视为二维查找。从这里开始,您可以通过使用一个基于一个的索引,并潜在地使用
x
a
Tuple
CartesianIndex
来提高性能,从而使这一点更具朱利安性。

因为您知道索引是两个元素向量,所以使用Tuple
(i,j)肯定会更好(从性能上看)
而不是向量
[i,j]
对于这个特定的问题,可能更切题:
x=(0,1);M[CartesianIndex(x.+1)]+=1
这并不能真正回答提示-需要对
x
的含义进行重组,而不是在IMO中对其进行充分描述。@MattB。我不明白为什么。OP自己说0对1只是一个建议。Julia基于1而不是基于0,因此1对2更有意义。一般来说,在任何语言中都不鼓励将变量命名为y00,y01而不是使用数组。我只是说我不明白您最初是如何重新构造示例的。我只是觉得你需要更多的解释,关于你是如何改变提示的,以及这种重构是如何解决问题中潜在的欲望的。也许否决票太苛刻了,但这就是为什么我认为值得加上我自己的答案。@MattB。是的,很公平,我在这篇评论之后看到了你的答案(+1),我想这可能就是你在这里的意思啊,我不反对。。。只是在这里,我一次又一次地发现(令我惊讶和失望的是),大多数问这种问题的人不喜欢(或阅读)详细的解释,而更喜欢用简短的片段来解决他们的问题。因此,这些天来,我尽量使事情简洁明了,至少尝试使用非模糊代码,希望通过使用提供的代码可以在较小的可消化块中提供必要的见解。@MattB。更令人沮丧的是,我在网站上的经验告诉我,压缩成更少行的完全相同的代码比适当间隔的代码有更多的机会被读取,即使压缩的版本要难看得多。令人沮丧,但是,你能做什么呢。