解決策を見つけたようですが、とにかくこれを分解しましょう。
Set
まず、元の値を交換するのではなく、元の値を適用する単純な転記エラーがあります。この変更により、基本的なコードが機能します。
i = 2;
x = {1, 1, 0, 0};
If[
x[[i]] == 1 && x[[i + 1]] == 0,
x[[i]] = 0; x[[i + 1]] = 1;
]
x
{1, 0, 1, 0}
これで、正常に変更されましx
た。これを関数にするには、 の値ではなくの名前をこのコードに渡す必要があります。これがエラーの原因です:x
x
{1, 1, 0, 0}[[2]] = 0;
パーツ割り当ての Set::setps: {1,1,0,0} はシンボルではありません。>>
必要なのは、関数の Hold 属性です。
SetAttributes[f, HoldAll]
f[i_, x_] := If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1;]
i = 2 ;
x = {1, 1, 0, 0};
f[2, x]
x
{1, 0, 1, 0}
おそらく、それ自体の値を変更するつもりはなかったかもしれませんx
が、この手法は他のアプリケーションで確実に役立ちます。上記の関数を変更してデータのコピーModule
を操作するには、使用する可能性があり、Hold 属性は必要ありません。
f2[i_, xImmutable_] :=
Module[{x = xImmutable},
If[x[[i]] == 1 && x[[i + 1]] == 0, x[[i]] = 0; x[[i + 1]] = 1];
x
]
i = 2 ;
x = {1, 1, 0, 0};
f2[2, x]
{1, 0, 1, 0}
x
withinModule
はローカル変数であり、変更されていないグローバル listではないことに注意してくださいx
。
楽しみのために、これを別の方法で実装してみましょう。
f3[i_, x_] :=
If[
x[[i + {0, 1}]] == {1, 0},
ReplacePart[x, {i -> 0, i + 1 -> 1}],
x
]
f3[2, x]
{1, 0, 1, 0}