-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; }

    }

现在我实例化两个这种类型的对象并向它们的属性添加一些值。

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 Min 和 Max 的值是否在 myItem2 Prop1-25 Min 和 Max 的值范围内

例子:

   myItem1.Prop1Min = 1
   myItem1.Prop1Max = 4

   myItem2.Prop1Min = 1
   myItem2.Prop1Max = 5

这是真的,因为 mtItem1 Prop1 min 和 max 在 myItem2 min 和 max 的范围内。

条件应该是 AND 在所有属性之间,所以最后在我们检查所有 25 个属性之后,如果它们都在第二个对象的范围内,我们返回 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

Linq 正在使用标准语句,例如 if...then,对于彼此而言,没有任何魔力 :)

如果最终目标只是比较,而不用说,哪些属性不在范围内,那么你不需要全部检查它们,对第一个不等于你可以结束检查。

因为您有这么多属性,所以您必须考虑将其保存在 Dictionary 或 List 中。或者使用动态属性(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 回答
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 回答