我有一个对象列表,列表中的每个对象都有以下属性:
首先,我需要找到所有将FirstDoseTime属性设置为特定值(1/1/1,12:00:00)的对象。让我们调用这些blankFirstDose对象。
然后,我需要搜索列表,看看对于每个blankFirstDose对象,列表中是否有另一个对象与blankFirstDose对象具有相同的属性,但FirstDoseTime属性除外(除了1/1 / 1,12:00:00)和FileName属性。
最后,我想从列表中删除任何具有不同FileName和FirstDoseTime的对应对象的blankFirstDose对象,该对象不是1/1/1,12:00:00。
这是我第一次这样做。此尝试成功运行,但是当我有大量这些对象时,需要花费太长时间。我需要更高效,更快速的东西。 谢谢你的帮助!
编辑:分析
我为一个"典型的"进行了一些系统分析。案例有助于为此讨论提供信息。在这种情况下,AllEvents列表包含40,928个LogFileEvent项,而blankFirstDoseLst包含12,092个项。
在我的系统上完成所有这些操作所需的时间大约为16秒。 几乎所有这16秒都用在两个foreach循环中。
var blankFirstDoseLst =
AllEvents.GroupBy(e => e.FirstDoseTime)
.Where(g => g.FirstOrDefault().FirstDoseTime == PatientModel.DEFAULT_DATE)
.SelectMany(g => g)
.ToList();
List<LogFileEvent> blanksToRemove = new List<LogFileEvent>();
foreach (var evt in AllEvents)
{
foreach (var blankEvt in blankFirstDoseLst)
{
if ((evt.FileName != blankEvt.FileName) &&
(evt.SwVersion == blankEvt.SwVersion) &&
(evt.ControllerSN == blankEvt.ControllerSN) &&
(evt.FirstDoseTime != blankEvt.FirstDoseTime) &&
(evt.EvtTime == blankEvt.EvtTime) &&
(evt.Evt == blankEvt.Evt) &&
(evt.EvtOutput == blankEvt.EvtOutput))
{
blanksToRemove.Add(blankEvt);
}
}
}
// Remove any duplicates ignoring first dose date and time
AllEvents.RemoveAll(e => blanksToRemove.Contains(e));
答案 0 :(得分:3)
您可以使用HashSet来保留应该删除的空白。
var blanksToRemove = new HashSet<LogFileEvent>();
然后是Contains
AllEvents.RemoveAll(e => blanksToRemove.Contains(e));
当你使用List时,将是一个O(1)操作,避免必须完成的线性搜索。如果使用列表,则包含它的时间复杂度为O(n)的顺序,其中n是列表中的项目数。
<强>更新强>
您可以做到的另一个变化如下。既然你想要
...搜索列表并查看是否为每个blankFirstDose 对象,列表中的另一个对象具有相同的精确度 属性为blankFirstDose对象,但FirstDoseTime除外 property(除了1/1 / 1,12:00之外的任何内容)和FileName 属性。
您可以删除第一个foreach语句的项目,如下所示:
foreach (var evt in AllEvents.Where(evt=>evt.FirstDoseTime != PatientModel.DEFAULT_DATE))
{
foreach (var blankEvt in blankFirstDoseLst)
{
if ((evt.FileName != blankEvt.FileName) &&
(evt.SwVersion == blankEvt.SwVersion) &&
(evt.ControllerSN == blankEvt.ControllerSN) &&
(evt.EvtTime == blankEvt.EvtTime) &&
(evt.Evt == blankEvt.Evt) &&
(evt.EvtOutput == blankEvt.EvtOutput))
{
blanksToRemove.Add(blankEvt);
}
}
}
这样做可以避免遍历blankFirstDoseLst
中AllEvents
项目中FirstDoseTime
项worker_processes auto;
user nginx;
events {
worker_connections 1024;
use epoll;
}
http {
tcp_nodelay on;
add_header Cache-Control no-cache;
upstream servers {
server 127.0.0.1:9999;
server 127.0.0.1:9998;
}
proxy_request_buffering on;
server {
listen 80;
client_max_body_size 200M;
client_body_buffer_size 200M;
server_name localhost;
location / {
try_files $uri @proxy_upload;
}
location @proxy_upload {
proxy_pass_request_body on;
proxy_pass http://servers;
}
}
}
与您要查找的值不同的项目。
答案 1 :(得分:1)
感谢您收到的所有回复。我最终使用了一个自定义IEqualityComparer的hashset策略,类似于@ZdeněkJelínek所提到的。自定义IEqualityComparer实现了我之前在“if”语句中执行的检查。
这大大减少了处理时间从16秒减少到约1秒。
// Remove any events with blank first dose time if there is a duplicate that has
// a valid first dose time
var blanksToRemove = new List<LogFileEvent>();
var blankFirstDoseEvts = AllEvents.Where(e => e.FirstDoseTime == PatientModel.DEFAULT_DATE)
.ToList();
var nonBlankFirstDoseEvts = new HashSet<LogFileEvent>(AllEvents.Where(e => e.FirstDoseTime != PatientModel.DEFAULT_DATE),
new BlankFirstDoseComparer());
foreach (var blankEvt in blankFirstDoseEvts)
{
if (nonBlankFirstDoseEvts.Contains(blankEvt))
{
blanksToRemove.Add(blankEvt);
}
}
AllEvents.RemoveAll(e => blanksToRemove.Contains(e));