源列表与目标列表的交集,并根据目标列表重新排序。

huangapple go评论63阅读模式
英文:

Intersection of a source and destination list with reordering based on the destination list

问题

我想要从这两个列表中返回共同属性的数组。
交集部分是有效的,但最终的重新排序与目标列表中已有的属性顺序不匹配。

private static PropertyInfo[] PropertyIntersection(Item dest, Item src)
{
    List<PropertyInfo> src_props = new(src.GetType().GetProperties());
    List<PropertyInfo> dest_props = new(dest.GetType().GetProperties());

    // 创建交集
    var ienum = src_props.Select(x => x.Name).Intersect(dest_props.Select(x => x.Name));
    List<PropertyInfo> list = src_props.Where(x => ienum.Contains(x.Name)).ToList();

    // 根据属性名称排序以匹配 dest_props 的顺序
    // 我应该如何按名称排序?
    return list.OrderBy(d => dest_props.IndexOf(d)).ToArray();
}

这里有什么我做错了的想法吗?

英文:

I want to return the array of common properties from these two lists.
The intersection is working, but the final reordering does not match the order of properties already present in the destination list.

private static PropertyInfo[] PropertyIntersection(Item dest, Item src)
{
    List&lt;PropertyInfo&gt; src_props = new(src.GetType().GetProperties());
    List&lt;PropertyInfo&gt; dest_props = new(dest.GetType().GetProperties());

    //Create the intersection
    var ienum = src_props.Select(x =&gt; x.Name).Intersect(dest_props.Select(x =&gt; x.Name));
    List&lt;PropertyInfo&gt; list = src_props.Where(x =&gt; ienum.Contains(x.Name)).ToList();

    // reorder to match order of dest_props
    // How do I order by name?                 
    return list.OrderBy(d =&gt; dest_props.IndexOf(d)).ToArray();
}

Any ideas what I'm doing wrong here?

答案1

得分: 1

你的代码存在一个问题,它具有**O(n2)的时间复杂度。因此,我建议使用具有O(1)查找时间复杂度的HashSet<T>。这将导致查询具有O(n)**的时间复杂度。

var src_props = src.GetType().GetProperties();
var dest_props = dest.GetType().GetProperties();

var srcNames = src_props.Select(p => p.Name).ToHashSet();
var intersection = dest_props.Where(p => srcNames.Contains(p.Name)).ToArray();

GetProperties方法返回一个数组,这是完全可以的。不需要创建列表。

请注意,Where扩展方法不会更改元素的顺序。由于我们将其应用于dest_props,结果将自动按照目标数组的顺序排序。


重要提示
Type.GetProperties方法的文档中写道:

在.NET 6及以前的版本中,GetProperties方法不会按照特定顺序返回属性,例如按字母顺序或声明顺序。您的代码不应依赖于属性返回的顺序,因为该顺序会变化。但是,从.NET 7开始,排序是基于程序集中的元数据顺序的确定性排序。

英文:

A problem with your code is that it has a O(n<sup>2</sup>) time complexity. Therefore, I suggest using a HashSet&lt;T&gt; which has a O(1) time complexity for lookups. This results in a query having O(n) time complexity.

var src_props = src.GetType().GetProperties();
var dest_props = dest.GetType().GetProperties();

var srcNames = src_props.Select(p =&gt; p.Name).ToHashSet();
var intersection = dest_props.Where(p =&gt; srcNames.Contains(p.Name)).ToArray();

The GetProperties method returns an array which is just fine. There is no need to create lists.

Note that the Where extension method does not change the order of the elements. Since we apply it to the dest_props, the result will automatically be sorted by this destination array.


Important:
The documentation for the Type.GetProperties Method says:
>In .NET 6 and earlier versions, the GetProperties method does not return properties in a particular order, such as alphabetical or declaration order. Your code must not depend on the order in which properties are returned, because that order varies. However, starting with .NET 7, the ordering is deterministic based upon the metadata ordering in the assembly.

huangapple
  • 本文由 发表于 2023年6月19日 21:13:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/76506989.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定