1

我试图找出除了Enumerable.Range在 WHERE 子句中一对一比较对象的元素之外还有什么更好的方法。

这可能是平行的,因为我们在这里一对一比较。

例如:House.Windows[0].color != House1.Windows[0].color然后 movenext to House.Windows[1].color != House1.Windows[1].color等等...

两个列表中的类型将相同。

    public class House
{
    string HouseNmbr;
    List<Window> windows;

}

public class Window
{
    string WSize;
    string WColor;
    bool IsEnergyEff;
}

public static class MyMain
{
    void Main()
    {
        House h1 = new House
        {
            HouseNmbr = "1",
            windows = new List<Window> { 
                new Window {Wsize="1", WColor = "blue",IsEnergyEff = true},
                new Window {Wsize="1", WColor = "black"},
                new Window {Wsize="1", WColor = "red"}
            }
        };

        House h2 = new House
        {
            HouseNmbr = "1",
            windows = new List<Window> { 
                new Window {Wsize="2", WColor = "blue",IsEnergyEff = false},
                new Window {Wsize="2", WColor = "black"}
            }
        };

        //Find the diffs...
        IEnumerable<House> updatesFromHouses = from id in h2 //Since h2 will have updates
                                             join pd in h1
                                             on id.HouseNmbr equals pd.HouseNmbr
                                               select new House
                                             {
                                                 windows = pd.windows.Where(
                                                    wn => Enumerable.Range(0, wn.windows.Count).All(ctr => wn.IsEnergyEff != id.windows[ctr].IsEnergyEff)
                                                 ).ToList()
                                             };            

    }
}
4

2 回答 2

3

如果您要一一比较,请使用Enumerable.Zip :

House.Windows.Zip(House1.Windows, (w, w1) => w.color != w1.color);

这将返回布尔值的集合,用于逐一比较颜色。您可以使用Any(b => !b)检查是否有任何不相等的颜色。

请记住,两个窗口列表应该具有相同的长度(只有相应的元素会产生结果)。因此,您可以在进行 zip 之前从检查列表长度开始。如果项目数不同,则列表不同。


为了比较窗口,您应该覆盖 Equals 和 GetHashCode 方法:

public class Window
{
    public string Size { get; set; }
    public string Color { get; set; }
    public bool IsEnergySaving { get; set; }

    public Window() { }

    public Window(string size, string color, bool isEnergySaving)
    {
        Size = size;
        Color = color;
        IsEnergySaving = isEnergySaving;
    }

    public override bool Equals(object obj)
    {
        Window other = obj as Window;
        if (other == null)
            return false;

        return Color == other.Color &&
               IsEnergySaving == other.IsEnergySaving;
    }

    public override int GetHashCode()
    {
        int hash = 19;            
        hash = hash * 23 + Color.GetHashCode();
        hash = hash * 23 + IsEnergySaving.GetHashCode();
        return hash;
    }
}

这是房子类略有改进:

public class House
{
    public House(string number)
    {
        Number = number;
        Windows = new List<Window>();
    }

    public string Number { get; private set; }
    public List<Window> Windows { get; private set; }

    public House WithWindow(string size, string color, bool energySaving = false)
    {
        Windows.Add(new Window(size, color, energySaving));
        return this;
    }
}

使用这个流畅的 API,您可以创建如下所示的房屋:

House h1 = new House("1")
                .WithWindow("1", "blue", true)
                .WithWindow("1", "black")
                .WithWindow("1", "red");

House h2 = new House("1")
                .WithWindow("2", "blue")
                .WithWindow("2", "black");

发现更改和新窗口将如下所示:

var changedAndNewWindows = h2.Windows.Except(h1.Windows);
于 2013-07-18T13:03:52.073 回答
0

您可以在这种情况下使用 Parallel.For ,因为您正在逐个元素地比较两个列表并且无需编辑(如果需要编辑,则必须使用锁定):

var count = Math.Min(h1.Windows.Count, h2.Windows.Count);
Parallel.For(0, count, (index)=>{
//Do your operations here
if(h1.Windows[index].Color == h2.Windows[index].Color)
{
}
});
于 2013-07-18T13:23:53.860 回答