-2

異なる値を持つ同じタイプの 2 つのオブジェクトがあります。

    public class Itemi
    {
    public Itemi()
    {

    }

    public int Prop1Min { get; set; }
    public int Prop1Max { get; set; }

    public int Prop2Min { get; set; }
    public int Prop2Max { get; set; }

    public int Prop3Min { get; set; }
    public int Prop3Max { get; set; }
    ...................................
    public int Prop25Min { get; set; }
    public int Prop25Max { get; set; }

    }

次に、このタイプの 2 つのオブジェクトをインスタンス化し、それらのプロパティにいくつかの値を追加します。

Itemi myItem1 = new Itemi();

myItem1.Prop1Min = 1;
myItem1.Prop1Max = 4;

myItem1.Prop2Min = 2;
myItem1.Prop2Max = 4;

myItem1.Prop3Min = -1;
myItem1.Prop3Max = 5;

.............................

myItem1.Prop25Min = 1;
myItem1.Prop25Max = 5;

Itemi myItem2 = new Itemi();

myItem2.Prop1Min = 1;
myItem2.Prop1Max = 5;

myItem2.Prop2Min = -10;
myItem2.Prop2Max = 3;

myItem2.Prop3Min = 0;
myItem2.Prop3Max = 2;

................................

myItem2.Prop25Min = 3;
myItem2.Prop25Max = 6;

この比較を行うための最良かつ最速の方法は何ですか:

  • myItem1 から各プロパティを取得し、Prop1-25 の最小値と最大値の値が myItem2 Prop1-25 の最小値と最大値の範囲内にあるかどうかを確認します

例:

   myItem1.Prop1Min = 1
   myItem1.Prop1Max = 4

   myItem2.Prop1Min = 1
   myItem2.Prop1Max = 5

mtItem1 Prop1 の最小値と最大値が myItem2 の最小値と最大値の範囲内にあるため、これは True です。

条件はすべてのプロパティ間で AND にする必要があるため、最後に 25 個のプロパティすべてをチェックした後、それらすべてが 2 番目のオブジェクトの範囲内にある場合は true を返します。

従来のif-else以外のLinqまたは他のアルゴリズムを使用してこれを行う高速な方法はありますか?

4

4 に答える 4

3

プロパティを次のようにリファクタリングします。

public class Item
{
    public List<Range> Ranges { get; set; }
}

public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }
}

次に、比較方法は次のようになります。

if (myItem1.Ranges.Count != myItem2.Ranges.Count)
{
    return false;
}

for (int i = 0; i < myItem1.Ranges.Count; i++)
{
    if (myItem1.Ranges[i].Min < myItem2.Ranges[i].Min ||
        myItem1.Ranges[i].Max > myItem2.Ranges[i].Max)
    {
        return false;
    }
}        
return true;

それ以外の場合は、リフレクションを使用する必要がありますが、これは決して高速ではありません。

于 2013-01-22T20:38:41.677 に答える
0

あなたは本当にGinosajiが提案したようなことをするべきです。

しかし、現在のデータモデルを使用したい場合は、次のように解決します。ハッピータイピング。:)

public static bool RangeIsContained(int outerMin, int outerMax, int innerMin, int innerMax)
{
    return (outerMin <= innerMin && outerMax >= innerMax);
}

public bool IsContained(Itemi outer, Itemi inner)
{
    return RangeIsContained(outer.Prop1Min, outer.Prop1Max, inner.Prop1Min, inner.Prop1Max)
        && RangeIsContained(outer.Prop2Min, outer.Prop2Max, inner.Prop2Min, inner.Prop2Max)
        // ...
        && RangeIsContained(outer.Prop25Min, outer.Prop25Max, inner.Prop25Min, inner.Prop25Max);
}

データモデルでは、これが基本的にリフレクション(遅い!)を除いて唯一の方法です。データが列挙できないため、LINQは役に立ちません。

于 2013-01-22T20:48:44.477 に答える
0

Linqは、if ... thenのような標準的なステートメントを使用しています。お互いに、魔法はありません:)

言うまでもなく、どのプロパティが範囲内にないかを比較するだけの最終目標の場合は、すべてをチェックする必要はありません。最初の不等式については、チェックを終了できます。

プロパティがたくさんあるので、たとえば辞書やリストに保存することを検討する必要があります。または、バインディングに使用する場合は、動的プロパティ(ITypedList )を使用します。

于 2013-01-22T20:42:29.773 に答える
0

完全を期すために、ここに LINQ ソリューションを示します (ただし、Ginosaji のソリューションよりもパフォーマンスが低く、読みにくいです!)

public class Range
{
    public int Min { get; set; }
    public int Max { get; set; }

    public static bool IsContained(Range super, Range sub)
    {
        return super.Min <= sub.Min
            && super.Max >= sub.Max;
    }
}

public class Itemi
{
    public Itemi()
    {
        properties = new Range[25];
        for (int i = 0; i < properties.Length; i++)
        {
            properties[i] = new Range();
        }
    }

    private Range[] properties;

    public IEnumerable<Range> Properties { get { return properties; } }

    public static bool IsContained(Itemi super, Itemi sub)
    {
        return super.properties
            .Zip(sub.properties, (first, second) => Tuple.Create(first, second))
            .All((entry) => Range.IsContained(entry.Item1, entry.Item2));
    }

    public Range Prop1 
    { 
        get { return properties[0]; }
        set { properties[0] = value; }
    }

    public Range Prop2
    {
        get { return properties[1]; }
        set { properties[1] = value; }
    }

    // ...
}
于 2013-01-22T21:43:42.567 に答える