C# - 使用LINQ进行子集列表迭代。 [英] C# - Subset list iteration with LINQ.

查看:92
本文介绍了C# - 使用LINQ进行子集列表迭代。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


你好,


我有以下DB列,我比较(_event ...< =)事件时间数据(以秒为单位)。




活动
999999; 1200; 800; 500; 300; 200; 60秒。 "999999"是列表的一部分,但它的目的是作为事件时间"代码",意思是"开始"。那么请你告诉我哪个是迭代到这个列表的更高效和优雅的解决方案,也许避免
分开两个?


我找不到办法而不是创建两个单独的列表,花费两次迭代...


//按时间列出事件 - OrderBy 60 => 999999


<跨度>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
var eventBySite = EVENTS.OrderBy(i => i.time)。其中(i => i。 company == data.company
&& i.time.ToString()。Length!= 6).Select(i =>
new {i.time,i.messagesID_FK,
i.gqs}。)ToList();


          ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
//按时间码列出


<跨度>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
var eventCodeBySite = EVENTS.OrderBy(i => i.time).Where(i => i。公司== data.company
&& i.time.ToString()。长度== 6)。选择(i =>
new {i.time,i.messagesID_FK,
i.gqs}。)ToList();


          ;&NBSP;&NBSP;
        


       &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
//查看时间码


<跨度>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
foreach var
_eventCode
in eventCodeBySite)


           &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
if (data.timeToChange == _eventCode.time)


< p style ="text-autospace:none">     &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
     
等待
Utility 。telegram(_eventCode.messagesID_FK,getDataById(data.machineID,data.company));
// messageId,data


&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;
if (_ eventCode.gqs ==
" YES"


                 &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
Utility .sendToGQS(data);


      ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
}


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
break ;


         ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
}


                  &NBSP;&NBSP;
}


                  &NBSP;&NBSP;
//查看时间事件


<跨度>&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
foreach var
_event
in eventBySite)


           &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
if (data.timeToChange< = _event.time)


    ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
await
Utility .telegram(_event.messagesID_FK,getDataById(data.machineID,data.company));
// messageId,data


&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP; &NBSP;&NBSP;
if (_ event.gqs ==
" YES"


                 &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
{


                  &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
Utility .sendToGQS(data);


      ;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
}


        &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
break ;


                   &NBSP;&NBSP;&NBSP;&NBSP;&NBSP;
}


                   
}


谢谢。


R。 Marco。


解决方案

I除了合并列表之外,没有看到您实际澄清原始问题的位置。这是你唯一的问题吗?

 //复制传递你的代码,没有尝试编译它

var events = EVENTS。 OrderBy(i => i.time)。其中(i => i.company == data.company&& i.time.ToString()。Length!= 6).Select(i => new {i.time,i.messagesID_FK,i.gqs})。ToList();


foreach(eventCodeBySite中的var _eventCode)
{
if(data.timeToChange == _eventCode.time)
{
await Utility .telegram(_eventCode.messagesID_FK,getDataById(data.machineID,data.company)); // messageId,data
if(_eventCode.gqs ==" YES")
{
Utility.sendToGQS(data);
};

休息;
} else if(data.timeToChange< = _event.time)
{
await Utility.telegram(_event.messagesID_FK,getDataById(data.machineID,data.company)); // messageId,data
if(_event.gqs ==" YES")
{
Utility.sendToGQS(data);
}
}
}

上面将枚举合并为一个。在您的代码中不清楚的是,在每个循环中,您在找到第一个匹配或第一个匹配后停止处理。鉴于你当时正在使用订单,时间会增加。


如果找到匹配项,第一个循环将运行一次。第二个循环似乎可能只是针对第一个元素运行然后停止(假设时间< value)。所以你不需要循环。只需使用FirstOrDefault。如果您想要
最后一项(时间< value),那么您应该通过降序使用订单。因此,"摆脱"的逻辑是每个循环都不清楚。


如果你真的只想在每个类别中处理1个项目,那么你可以添加一个变量来跟踪你何时完成if语句的逻辑并跳过它之后。但这对我来说似乎很奇怪,因为你没有澄清你的逻辑,我没有把它放进去。


你还应该考虑下降顺序,然后你会更快地通过列表如果它是一个不断增加的列表。


这是最终版本,应该模仿你想要的。

 //复制 - 传递你的代码,没有尝试编译它

//移动OrderBy结束所以首先发生的位置和过滤
var events = EVENTS.Where(i => i.company == data.company&& i.time.ToString()。Length!= 6).Select(i => new {i.time,i.messagesID_FK,i.gqs})。OrderBy(i => ; i.time)。ToList();

//跟踪匹配和最早的事件
var foundMatching = false;
var foundEarliest = false;

foreach(eventCodeBySite中的var _eventCode)
{
if(!foundMatching&& data.timeToChange == _eventCode.time)
{
await Utility.telegram(_eventCode.messagesID_FK,getDataById(data.machineID,data.company)); // messageId,data
if(_eventCode.gqs ==" YES")
{
Utility.sendToGQS(data);
};

foundMatching = true;
}否则if(!foundEarliest&& data.timeToChange< = _event.time)
{
await Utility.telegram(_event.messagesID_FK,getDataById(data.machineID,data。公司)); // messageId,data
if(_event.gqs ==" YES")
{
Utility.sendToGQS(data);
}
foundEarliest = true;
}

//找到每个
中的一个if(foundMatching&& foundEarliest)
break;
}



Hello,

I have the following DB column which I compare (_event…<=) events time data (in seconds).

EVENTS: 999999; 1200; 800; 500; 300; 200; 60 -- seconds. "999999" is part of the list but it’s intended as event time "code" and means "start". By the way can you please tell me which is the more efficient and elegant solution for iterating into this list, maybe avoid to have two separated ?

I have no find a way rather than create two separate lists which costs two iteration …

//List by time events - OrderBy 60 => 999999

                    var eventBySite = EVENTS.OrderBy(i => i.time).Where(i => i.company == data.company && i.time.ToString().Length != 6).Select(i => new { i.time, i.messagesID_FK, i.gqs }).ToList();

                    //List by time codes

                    var eventCodeBySite = EVENTS.OrderBy(i => i.time).Where(i => i.company == data.company && i.time.ToString().Length == 6).Select(i => new { i.time, i.messagesID_FK, i.gqs }).ToList();

                    

                    //looking into time codes

                    foreach (var _eventCode in eventCodeBySite)

                    {

                        if (data.timeToChange == _eventCode.time)

                        {

                            await Utility.telegram(_eventCode.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data

                            if (_eventCode.gqs == "YES")

                            {

                                Utility.sendToGQS(data);

                            }

                            break;

                        }

                    }

                    //looking into time events

                    foreach (var _event in eventBySite)

                    {

                        if (data.timeToChange <= _event.time)

                        {

                            await Utility.telegram(_event.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data

                            if (_event.gqs == "YES")

                            {

                                Utility.sendToGQS(data);

                            }

                            break;

                        }

                    }

Thanks.

R. Marco.

解决方案

I don't see where you actually clarified what your original problem was other than to consolidate the lists. Is that your only question?

//Copy-passed your code, didn't try to compile it

var events = EVENTS.OrderBy(i => i.time).Where(i => i.company == data.company && i.time.ToString().Length != 6).Select(i => new { i.time, i.messagesID_FK, i.gqs }).ToList();

   
foreach (var _eventCode in eventCodeBySite)
{
   if (data.timeToChange == _eventCode.time)
   {
      await Utility.telegram(_eventCode.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data
      if (_eventCode.gqs == "YES")
      {
         Utility.sendToGQS(data);
      };

      break;
   } else if (data.timeToChange <= _event.time)
   {
      await Utility.telegram(_event.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data
      if (_event.gqs == "YES")
      {
         Utility.sendToGQS(data);
      }
   }
}

The above combines the enumerations into one. What is unclear in your code is that in each loop you stop processing after you find the first match or first less than. Given you're using order by then the time would be incrementing.

The first loop would run once if you find a match. The second loop seems like it would probably just run against the first element and then stop (assuming time < value). So you don't need a loop for that. Just use FirstOrDefault. If you instead want the last item (time < value) then you should be using an order by descending. So the logic to "get out of" each loop is unclear.

If you really only want to process 1 item in each category then you could add a variable to track when you've done the logic for the if statement and skip it after that. But this seems odd to me and since you didn't clarify your logic I didn't put it in.

You should also consider ordering descending and then you'd get through the list faster if it is an ever incrementing list.

Here's the final version that should mimic what you want.

//Copy-passed your code, didn't try to compile it

//Moved OrderBy to end so the where and filtering occurred first
var events = EVENTS.Where(i => i.company == data.company && i.time.ToString().Length != 6).Select(i => new { i.time, i.messagesID_FK, i.gqs }).OrderBy(i => i.time).ToList();

//Track the matching and earliest events
var foundMatching = false;
var foundEarliest = false;
   
foreach (var _eventCode in eventCodeBySite)
{
   if (!foundMatching && data.timeToChange == _eventCode.time)
   {
      await Utility.telegram(_eventCode.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data
      if (_eventCode.gqs == "YES")
      {
         Utility.sendToGQS(data);
      };

      foundMatching = true;
   } else if (!foundEarliest && data.timeToChange <= _event.time)
   {
      await Utility.telegram(_event.messagesID_FK, getDataById(data.machineID, data.company)); //messageId, data
      if (_event.gqs == "YES")
      {
         Utility.sendToGQS(data);
      }
      foundEarliest = true;
   }

   //Found one of each
   if (foundMatching && foundEarliest)
      break;
}


这篇关于C# - 使用LINQ进行子集列表迭代。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆