从 Ienumerable.except 获取确切的差异
本文关键字:Ienumerable except 获取 | 更新日期: 2023-09-27 18:34:44
我正在使用 LINQ ENumerable.除了从 MyType 的两个列表中获取差异。当我找到差异时,我需要检索相应差异项的基础和比较列表中的不同之处。喜欢
我有两个列表要比较
Base:
Name="1",Type="a",Switch="384347324372432"
Name="1",Type="b",Switch="43432432423"
Name="2",Type="q",Switch="4324324234"
Compare List:
Name="1",Type="a",Switch="aAAAA384347324372432"
Name="1",Type="c",Switch="23432432"
Name="2",Type="q",Switch="3423432423432"
Name="2",Type="q",Switch="4324324234"
Ouuput将是
Found diff.
Base:
Name="1",Type="a",Switch="384347324372432"
Corresponding compare value:
Name="1",Type="a",Switch="aAAAA384347324372432"
etc...
我已经编写了自己的类对象,例如MyType,用于将这些存储为项目属性
定义了一个自定义比较器,例如
class mycomparer: System.Collections.Generic.IEqualityComparer<MyType>
{
public mycomparer() {}
public bool Equals(MyType type1, MyType type2)
{
return ( (type1.Name.ToLower() == type2.Name.ToLower()) && (type1.Type.ToLower() == type2.Type.ToLower()) (type1.Switch.ToLower() == type2.Switch.ToLower())
}
public int GetHashCode(MyType type)
{
return string.concat(type.Name, type.Type, type.Switch).ToLower().GetHashCode();
}
}
在我的代码中,我使用
MyComparer mine = new MyComparer();
IEnumerable<MyType> diff = baseList.Except(compareList,mine);
我正确理解了差异。但是对于基线列表中的不同值,我想知道比较列表中的相应值是什么。
我愿意
foreach(Mytype type in diff)
{
Console.writeline(type.Name+type.Type+type.Switch);
}
如何获取比较列表的相应值。
我尝试了类似的东西,
IEnumerable<MyType> compareValue = Comparelist.Where(tempFile => tempFile.Name.ToLower() == type.Name.ToLower() && tempFile.Type.ToLower() == process.Type.ToLower()
(基本上,switch在这里可能大部分不同(
但问题是,在某些情况下,可能存在重复的 Name=" Type=",所以上面的 where 检索了多个项目,所以对应的比较列表值会有所不同。
我尝试从 Equal 方法编写差异值,但对我不起作用。
更新:
在发现重复名称和类型并且开关不匹配的情况下,我认为 diff 计算正确,但是当输出写入控制台时,写入了不正确的差异值,这是示例。
Base:
Name="2",Type="q",Switch="4324324234"
Name="2",Type="q",Switch="3423432423432"
Compare List:
Name="2",Type="q",Switch="4324324234"
Name="2",Type="q",Switch="3423432423432dwqdwqdwqdqwdwdq"
base.except(compare) (as used in my sample code or Moho's solution) gets the diff correctly,
但与 diffSwitch.ToList((.福尔每
我会得到类似的东西
base: Name="2",Type="q",Switch="3423432423432"
Compare: Name="2",Type="q",Switch="4324324234"
你看这不是相应的不匹配。事实上,Switch="4324324234"匹配正确。这就是我看到的问题。
谢谢。
让两个列表都命名为 list
和 list2
。这是一个解决方案:
var common = list1.Intersect(list2, new mycomparer());
var result = list1.Concat(list2)
.Except(common, new mycomparer())
.GroupBy (x => new { x.Name, x.Type } );
因此,两个列表都连接起来,然后删除两个列表中共有的元素,最后其余项目按Name
和Type
分组。
也许有用的补充是,如果MyType
是一个struct
,你不需要比较器,因为当结构的值相等时,它们是相等的。
试试这个
baseList.Except( compareList, mine ).Union( compareList.Except( baseList.Except, mine ) )
根据新要求进行编辑:
var baseList = new List<MyType>()
{
new MyType() { Name="1",Type="a",Switch="384347324372432" },
new MyType() { Name="1",Type="b",Switch="43432432423" },
new MyType() { Name="2",Type="q",Switch="4324324234" }
};
var compareList = new List<MyType>()
{
new MyType() { Name="1",Type="a",Switch="aAAAA384347324372432" },
new MyType() { Name="1",Type="c",Switch="23432432" },
new MyType() { Name="2",Type="q",Switch="3423432423432" },
new MyType() { Name="2",Type="q",Switch="4324324234" }
};
// matched Name/Type w/ different Switch
var diffSwitches = baseList.Join( compareList,
bl => new { bl.Name, bl.Type },
cl => new { cl.Name, cl.Type },
( bl, cl ) => new {
baseItem = bl,
compareItem = cl } )
.Where( o => o.baseItem.Switch != o.compareItem.Switch );
diffSwitches.ToList().ForEach(i => Console.WriteLine("{0}-{1}: {2}; {3}", i.baseItem.Name, i.baseItem.Type, i.baseItem.Switch, i.compareItem.Switch));
我认为您可以通过稍微更改比较器来获得所需的结果:
class mycomparer : System.Collections.Generic.IEqualityComparer<Item>
{
bool customcomparer = false;
public mycomparer(bool custom = false)
{
customcomparer = custom;
}
public bool Equals(Item type1, Item type2)
{
return GetHashCode(type1) == GetHashCode(type2);
}
public int GetHashCode(Item type)
{
if (customcomparer)
return string.Concat(type.Name, type.Type).ToLower().GetHashCode();
return string.Concat(type.Name, type.Type, type.Switch).ToLower().GetHashCode();
}
}
您的课程设置如下:
public class MyType
{
public String Name, Type, Switch;
public MyType()
{
}
public MyType(string _name, string _type, string _switch)
{
Name = _name;
Type = _type;
Switch = _switch;
}
public override string ToString()
{
return "Name = " + this.Name + ",Type = " + this.Type + ",Switch = " + this.Switch;
}
}
第二个 IEnumerable 像这样:
private void button3_Click(object sender, EventArgs e)
{
mycomparer mine = new mycomparer();
mycomparer mine2 = new mycomparer(true);
IEnumerable<MyType> diff = baseList.Except(compareList, mine);
IEnumerable<MyType> diff2 = compareList.Intersect(diff, mine2);
string message = "Base:'n";
foreach (MyType item in diff)
{
message += item.ToString() + "'n";
}
message += "Corresponding compare value:'n";
foreach (MyType item in diff2)
{
message += item.ToString() + "'n";
}
MessageBox.Show(message);
}
我注意到diff
返回 2 个项目名称 1 类型 a 和名称 1 类型 b。 这是来自您的原始代码,所以我就这样离开了。