C#:与包含列表的区别
我有一个类的实例列表。每个实例都包含一个 IList 属性和一个自定义类的对象。现在我想删除此列表中的所有离散实例,其中包含的 IList-Property 和 MyMulti-Class 的 Multi-Property 的元素是相等的。我只想保留列表中的一个元素,其中“someData”属性的“First”属性最低。 我的建议是,通过包含 IList 属性和“SomeData”属性的“Multi”属性对列表的元素进行分组,然后按“SomeData”属性的“First”属性和选择每组的第一个元素。
我需要它尽可能高性能。有人有什么想法吗?
示例:
class myClass
{
public IList<String> SomeStrings { get; set; }
public MyMulti SomeData { get; set; }
public myClass(MyMulti data, params string[] strings)
{
SomeData = data;
SomeStrings = strings;
}
}
class MyMulti
{
public int First { get; set; }
public int Second { get; set; }
public int Multi
{
get
{
return First * Second;
}
}
public MyMulti(int first, int second)
{
First = first;
Second = second;
}
}
var mc1 = new myClass(new MyMulti(6, 4), "0", "1");
var mc2 = new myClass(new MyMulti(3, 8), "0", "1");
var mc3 = new myClass(new MyMulti(7, 3), "0", "1");
var mc4 = new myClass(new MyMulti(2, 35), "0", "2");
var mc5 = new myClass(new MyMulti(5, 4), "1", "1");
var mc6 = new myClass(new MyMulti(7, 10), "0", "2");
IList<myClass> aList = new List<myClass>(){mc1, mc2, mc3, mc4, mc5, mc6};
var query = aList.GroupBy(x =>
new
{
x.SomeData.Multi,
x.SomeStrings
// don't work cause this will compare the lists
// not the containing elements
})
.Select(x=>
x.OrderBy(y=>
y.SomeData.First)
.First());
结果应为:mc1 和 mc2 分组然后删除 mc1、mc3 自己的组,mc4 和 mc6 分组然后删除 mc6,mc5 自己的组 --> mc2、mc3、mc4、mc5 应保留
编辑:
如果我首先按 MyClass.SomeData.First 属性对列表进行排序,然后使用 List.Distinct() 方法和自定义 IEqalityComparer 实现,我将得到我正在搜索的内容为了。但这是最有效的方法吗?
public class myClassEqualityComparer : IEqualityComparer<myClass>
{
public bool Equals(myClass x, myClass y)
{
if (!x.SomeData.Multi.Equals(y.SomeData.Multi))
return false;
else
if (x.SomeStrings.AsEnumerable()
.SequenceEqual(y.SomeStrings.AsEnumerable()))
return true;
return false;
}
public int GetHashCode(myClass obj)
{
int hCode = obj.SomeData.Multi;
foreach (var item in obj.SomeStrings)
{
hCode = hCode ^ item.GetHashCode();
}
return hCode.GetHashCode();
}
}
I have a List of instances of a class. Each instance contains a IList-property and a object of a custom class. Now I want to drop all distict instances in this List, where the elements of the containing IList-Property and the Multi-Property of the MyMulti-Class are equal. I want to remain only the one element in the List, where the "First"-property of the "someData"-Property is the lowest.
My suggestion was, to group the elements of the List by the containing IList-Property and the "Multi"-property of the "SomeData"-property and then sort it by the "First"-property of the "SomeData"-Property and select the first Element of each group.
I need it as performant as possible. Anyone any ideas?
Example:
class myClass
{
public IList<String> SomeStrings { get; set; }
public MyMulti SomeData { get; set; }
public myClass(MyMulti data, params string[] strings)
{
SomeData = data;
SomeStrings = strings;
}
}
class MyMulti
{
public int First { get; set; }
public int Second { get; set; }
public int Multi
{
get
{
return First * Second;
}
}
public MyMulti(int first, int second)
{
First = first;
Second = second;
}
}
var mc1 = new myClass(new MyMulti(6, 4), "0", "1");
var mc2 = new myClass(new MyMulti(3, 8), "0", "1");
var mc3 = new myClass(new MyMulti(7, 3), "0", "1");
var mc4 = new myClass(new MyMulti(2, 35), "0", "2");
var mc5 = new myClass(new MyMulti(5, 4), "1", "1");
var mc6 = new myClass(new MyMulti(7, 10), "0", "2");
IList<myClass> aList = new List<myClass>(){mc1, mc2, mc3, mc4, mc5, mc6};
var query = aList.GroupBy(x =>
new
{
x.SomeData.Multi,
x.SomeStrings
// don't work cause this will compare the lists
// not the containing elements
})
.Select(x=>
x.OrderBy(y=>
y.SomeData.First)
.First());
Result should be: mc1 and mc2 grouped and then drop mc1, mc3 own group, mc4 and mc6 grouped and then mc6 droped, mc5 own group --> mc2, mc3, mc4, mc5 should remain
EDIT:
If I first sort the List by the MyClass.SomeData.First-property and then use the List.Distinct()-method and a custom IEqalityComparer implementiation I get, what I'm searching for. But is this the most performant way to do this?
public class myClassEqualityComparer : IEqualityComparer<myClass>
{
public bool Equals(myClass x, myClass y)
{
if (!x.SomeData.Multi.Equals(y.SomeData.Multi))
return false;
else
if (x.SomeStrings.AsEnumerable()
.SequenceEqual(y.SomeStrings.AsEnumerable()))
return true;
return false;
}
public int GetHashCode(myClass obj)
{
int hCode = obj.SomeData.Multi;
foreach (var item in obj.SomeStrings)
{
hCode = hCode ^ item.GetHashCode();
}
return hCode.GetHashCode();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
为什么不尝试 Distinct() 方法可能会完成你的工作
<代码>List.Distinct();
why dont you try Distinct() method might do your wrok
List.Distinct();
GetHashCode 函数可能会减慢速度。
哈希码用于平衡哈希表,为了获得最佳性能,哈希函数必须为所有输入生成随机分布。您应该尝试:
您可以使用 System.Diagnostics.Stopwatch 测试性能并循环 100000 到 1000000 次。
you GetHashCode function may slow thing down.
Hash code is used to balance hash table and for the best performance, a hash function must generate a random distribution for all input. You should try:
You may test performance using System.Diagnostics.Stopwatch and loop 100000 to 1000000 times.