3

配列 [1, 2, 3] を彼の順列の 1 つのインスタンスと考えてください。

私のコードでは、この値を変数に関連付けて、名前で参照できるようにする必要があります

Python版として読みやすくシンプルなコードを取得しようとしています

Python の場合:

permutation = [2, 1, 3]

できるよ:

for (red, green, blue) in permutation
for (a, b, c) in permutation
if b is red

...

私がする必要があるのは、特定の順列の値をまったく同じ順序で変数に関連付けることです: [2, 1, 3] 順列と (赤、緑、青) 変数がある場合、赤 = 2 緑 =1 を発生させたい青 = 3

C# では、Dictionary または OrderedDictionary、意味のある名前の ExtensionMethod によってそのようなことが実現できると思います。おそらく、colors["red"] == letters["a"] のようなもので問題ありません。

さまざまな実装をスケッチしようとしましたが、何かが足りないと思います。これは私がスケッチしたものです。

enum ColorsEnum
{
    red, green, blue
}

public static Dictionary<string, int> Valorize(IEnumerable<string> keys, IEnumerable<int> values)
    {
           ...
    }

public static Dictionary<string, int> AsColorDictionaryWithValues(this string[] keys, int[] values)
{
           ...
}

public static void Valorize(Dictionary<string, int> dic, IEnumerable<int> values)
{
    foreach (var item in Enum.GetNames(typeof(ColorsEnum)))
    {
        dic.Add(item, [incremental_number]);
    }
}

良い解決策は何だと思いますか (読みやすさとシンプルさが重要です)

4

2 に答える 2

4

このような拡張メソッドをお探しですか?

public static void Do<T1, T2, T3>(this Tuple<T1, T2, T3> tuple,
                                  Action<T1, T2, T3> action)
{
    action(tuple.Item1, tuple.Item2, tuple.Item3);
}

使用法:

var list = new List<Tuple<int, int, int>>
{
    Tuple.Create(255, 0, 0),
    Tuple.Create(0, 255, 0),
    Tuple.Create(0, 0, 255),
};

list.ForEach(t => t.Do((red, green, blue) =>
{
    Console.WriteLine("R: {0}, G: {1}, B: {2}", red, green, blue);
}));

出力:

R: 255, G: 0, B: 0
R: 0, G: 255, B: 0
R: 0, G: 0, B: 255
于 2012-04-26T11:09:58.280 に答える
0

ForEachBundle私はあなたが望むことをするために、私が呼んだかなり単純な拡張メソッドをまとめました。

たとえば、次の配列があるとします。

var xs = new [] { 1, 2, 3, 4, 5, 6, };

次に、次ForEachBundleのように呼び出します。

xs.ForEachBundle(
    (red, green, blue)
        => Console.WriteLine("{0}:{1}:{2}", red, green, blue));

結果は次のとおりです。

1:2:3
4:5:6

この例で列挙型に 7 番目の値がある場合、その「余分な」値は単に無視されると想定しました。それ以外の場合、この状況に対処する必要がある場合は、コードを変更してデフォルト値または null 許容型を使用できます。

の私の定義は次のForEachBundleとおりです。

public static void ForEachBundle<T>(
    this IEnumerable<T> @this,
    Action<T, T, T> action)
{
    if (@this == null) throw new System.ArgumentNullException("@this");
    var a = action;
    if (a == null) throw new System.ArgumentNullException("action");
    using (var en = @this.GetEnumerator())
    {
        while (true)
        {
            if (en.MoveNext())
            {
                var t0 = en.Current;
                if (en.MoveNext())
                {
                    var t1 = en.Current;
                    if (en.MoveNext())
                    {
                        var t2 = en.Current;
                        a(t0, t1, t2);
                    }
                    else break;
                }
                else break;
            }
            else break;
        }
    }
}

これがあなたの要件を満たしているかどうか教えてください。


不完全な「バンドル」のデフォルト値を追加するバージョンは次のとおりです。

public static void ForEachBundle<T>(
    this IEnumerable<T> @this,
    Action<T, T, T> action)
{
    if (@this == null) throw new System.ArgumentNullException("@this");
    var a = action;
    if (a == null) throw new System.ArgumentNullException("action");
    using (var en = @this.GetEnumerator())
    {
        while (en.MoveNext())
        {
            var t0 = en.Current;
            var t1 = en.MoveNext() ? en.Current : default(T);
            var t2 = en.MoveNext() ? en.Current : default(T);
            a(t0, t1, t2);
        }
    }
}
于 2012-04-26T12:17:34.360 に答える