简体   繁体   English

在C#中通用列表中合并具有相同类型的项目的最有效方法是什么?

[英]What is the most efficient way to merge items with the same type in a generic list in C#?

Example, I have the following interface and classes: 例如,我有以下接口和类:

public interface IRole {
    DateTime Since {get;}
    DateTime Until {get;}
}

public class Manager : IRole {
    public DateTime Since {get; private set;}
    public DateTime Until {get; private set;}
}
public class Employee : IRole {
    public DateTime Since {get; private set;}
    public DateTime Until {get; private set;}
}
public class Ceo: IRole {
    public DateTime Since {get; private set;}
    public DateTime Until {get; private set;}
}

If a generic list contains the following items: 如果通用列表包含以下项目:

list[0]=new Manager();
list[1]=new Manager();
list[2]=new Employee();
list[3]=new Manager();
list[4]=new Ceo();
list[5]=new Ceo();

And I shall merge the same types, combine the Since/Until and shrink the items in list, so the output becomes: 并且我将合并相同的类型,组合Since / Until并缩小列表中的项目,因此输出变为:

newList[0]=new Manager() //(Since is from list[0], Until is from list[1])
newList[1]=new Employee() //(list[2])
newList[2]=new Manager() //(list[3])
newList[3]=new Ceo() //(Since is from list[4], Until is from list[5])

Please make sure you understand the question before answering as I have a history of being ambigous and I don't want to upset people. 在回答之前请确保你理解这个问题,因为我有一个暧昧的历史,我不想让人不安。 So please comment if you feel the "requirement" isn't clear. 如果您觉得“要求”不明确,请发表评论。

My way is kind of dumb: 我的方式有点愚蠢:

for each item in list
    the current item shall always be merged into the previous item
        check if current item has the same type as the previous item
            get last item from newList and merge last item with current item

I was just wondering there must be a better solution. 我只是想知道必须有一个更好的解决方案。

Updated: 更新:

I just realize my "dumb solution" won't cover cases like more than 2 continuous items with the same type. 我只是意识到我的“愚蠢的解决方案”不会涵盖超过2个相同类型的连续项目。

Example: 例:

list[0]=new Manager();
list[1]=new Manager();
list[2]=new Employee();
list[3]=new Manager();
list[4]=new Ceo();
list[5]=new Ceo();
list[6]=new Ceo();

I wrote a blog post about this :-). 我写了一篇关于此的博客文章 :-)。

It feels almost like group by except, you don't want to group elements globally. 它感觉几乎像group by除了你不想全局分组元素。 Instead, you only want to group elements that are adjacent in the input list. 相反,您只想对输入列表中相邻的元素进行分组。 The blog post provides some code that allows you to change the meaning of group by in the LINQ query, so you could write just: 博客文章提供了一些代码,允许您在LINQ查询中更改group by的含义,因此您可以只编写:

var groups =
  from person in list.WithAdjacentGrouping()
  group person by person.GetType().Name into g
  select new { 
    Type = g.Key,
    Since = new DateTime(g.Select(p => p.Since.Ticks).Min()),
    Until = new DateTime(g.Select(p => p.Until.Ticks).Max())
  }

The call to WithAdjacentGrouping specifes that grouping should only group adjacent elements. WithAdjacentGrouping的调用WithAdjacentGrouping分组应仅对相邻元素进行分组。 Then we can collect adjacent groups of persons by type (using GetType().Name as the key). 然后我们可以按类型收集相邻的人群(使用GetType().Name作为键)。

Finally, we return a collection that contains the name of the type (eg "Ceo") and two times - Since and Until that are calculated as minimal/maximal time from the collected group. 最后,我们返回一个包含类型名称的集合(例如“Ceo”)和两次 - SinceUntil计算为收集组的最小/最大时间。

I don't think your pseudo code is dumb at all if it works as you expect it to. 我不认为你的伪代码是愚蠢的,如果它按你期望的那样工作。 I don't believe you're going to find an easy shortcut for what you're trying to do, since it's a rather unusual algorithm. 我不相信你会为你想要做的事情找到一个简单的捷径,因为这是一个相当不寻常的算法。 Bottom line: if this algorithm is not going to be run millions of times a day and the list doesn't have millions of objects in it, I wouldn't worry about efficiency. 底线:如果这个算法不会每天运行数百万次并且列表中没有数百万个对象,我不会担心效率。

List<IRole> newList = new Lis<IRole>();
for (int i = 1; i < list.Count; i++) // Start at 1, so we can do i - 1 on the first iteration
{
  if (list[i - 1].GetType() != list[i].GetType()) // they're not the same
  {
    newList.Add(list[i - 1]); // so add the first one too
  }
  newList.Add(list[i]); // always add second one
}

I believe this is a very requirement specific thing. 我相信这是一项非常具体的要求。 I am not sure if this is to be supported by a framework in anyway. 我不确定这是否会得到框架的支持。 What happens if the type is not derived from IRole directly. 如果类型不是直接从IRole派生,会发生什么。 What if there is something like IEmployee from which IManager is derived. 如果有类似IEmployee的东西从IManager派生出来会怎样。 I am not sure how application specific symentics can be understood by framework. 我不确定框架是如何理解应用程序特定的symentics的。

If the question is very specific to application, you may be able to use linq to get this done using group clause (on type). 如果问题非常特定于应用程序,您可以使用linq来使用group子句(在类型上)完成此操作。 I haven't tried this before hence can't give you the exact solution. 我之前没有尝试过,因此无法给出确切的解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用C#,比较/合并两个相同类型的通用列表的有效方法是什么? - Using C#, what's an efficient way to compare/merge two generic lists of the same type? 在C#中将多个2 xml文件与同一模式合并在一起的最有效方法是什么? - What is the most efficient way in C# to merge more than 2 xml files with the same schema together? 最有效的方法是获取在C#中采用任何类型的可索引列表的方法 - What's the most efficient way to have a method that takes an indexable list of any type in c# 什么是C#中最通用的函数类型 - What is the most generic function type in c# 根据嵌套列表中包含的 id 元素比较两个通用列表的最有效方法 (C#) - Most efficient way to compare two generic lists based on id elements contained within nested list (C#) 合并包含列表的字典的最有效方法是什么 - What is the most efficient way to merge dictionaries containing a list 在C#中,合并数组中项目的最优雅方式是“单个较大项目”的一部分? - In C#, what is the most elegant way to merge items in an array are part of a “single larger item”? 从同一来源生成多个图像的最有效方法是什么? C#/Asp.Net - What's the most efficient way to generate multiple images from the same source? C# / Asp.Net 使用C#在ComboBox中放置驱动器列表的最有效方法是什么? - What is the most efficient way to place a list of drives in a ComboBox using C#? 在Razor C#中呈现HTML表的最有效方法是什么 - What is the most efficient way to render a HTML Table in Razor C#
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM