0

特定の範囲に属する数値の関数で値を割り当てるエレガントな方法を探しています。

たとえば、数値が X の場合、 は次のelegant wayように返します。

  • 'a' - X が 0 ~ 1000 の場合
  • 'b' - X が 1000 ~ 1500 の場合
  • など(ただし、定義された間隔の固定数)

エレガントとは、より魅力的なものを意味します

if ((x => interval_1) && (x < interval_2))
    class_of_x = 'a';
else if ((x => interval_2) && (x < interval_3))
    class_of_x = 'b';
...

また

if(Enumerable.Range(interval_1, interval_2).Contains(x))
    class_of_x = 'a';
else if(Enumerable.Range(interval_2 + 1, interval_3).Contains(x))
    class_of_x = 'b';
...

たくさんの IF を見るのは嫌いです。また、interval_1、interval_2 などのように、interval 値をコレクションに保存することもできます (これは IS をなくすのに役立つのではないでしょうか?)。

この質問にいくらか触発されました 数値が範囲内にあるかどうかをエレガントにチェックする方法は? 上記の問題の解決策を探しているときに出てきたものです。

4

5 に答える 5

1

拡張メソッドを作成できます:

public static class IntExtensions
{
    // min inclusive, max exclusive
    public static bool IsBetween(this int source, int min, int max)
    {
        return source >= min && source < max
    }
}

その後

// Item1 = min, Item2 = max, Item3 = character class
IList<Tuple<int, int, char>> ranges = new List<Tuple<int, int, char>>();
// init your ranges here
int num = 1;
// assuming that there certainly is a range which fits num,
// otherwise use "OrDefault"
// it may be good to create wrapper for Tuple, 
// or create separate class for your data
char characterClass = ranges.
                        First(i => num.IsBetween(i.Item1, i.Item2)).Item3;
于 2013-08-14T15:17:12.900 に答える
1

最初に、包括的な最大値と、そのバンドに使用する対応する値を保持する小さなクラスを定義します。

sealed class Band
{
    public int  InclusiveMax;
    public char Value;
}

次に、各バンドに使用する値を指定する配列を宣言し、Band任意の入力に対応するバンド値を見つけるためにループします。

public char GetSetting(int input)
{
    var bands = new[]
    {
        new Band {InclusiveMax = 1000, Value = 'a'},
        new Band {InclusiveMax = 1500, Value = 'b'},
        new Band {InclusiveMax = 3000, Value = 'c'}
    };

    char maxSetting = 'd';

    foreach (var band in bands)
        if (input <= band.InclusiveMax)
            return band.Value;

    return maxSetting;
}

bands注: 実際のコードでは、(上記のコードのように) 呼び出されるたびに配列を初期化するのではなく、配列を 1 回だけ初期化するクラスにこれらすべてをラップします。

于 2013-08-14T15:21:15.337 に答える
1

私のコメントが正しい場合、最初の if ステートメントには多くの不要なチェックがあります。間隔 2 よりも小さくない場合は、次の値以上でなければなりません。したがって、次のようになります。

if((x => i1) && (x < i2))
else if(x < i3)
else if(x < i4)...

「真の」引数が見つかった場合、条件が整っている限り、if ステートメントの残りの部分は無関係です。これはニーズに合うはずです。

于 2013-08-14T15:15:00.733 に答える
0

ここで、実装する静的な System.Linq.Enumerable の Range() メソッドを使用することもできます。

IEnumerable<T>

Contains() メソッド (再び System.Linq.Enumerable から) を使用して、次のようなことを行います。

var num = 254;
if(Enumerable.Range(100,300).Contains(num)) { ...your logic here; }

これは、少なくとも私の目にはよりエレガントに見えます。

于 2013-11-08T09:07:48.717 に答える