Convert nested for-loops into single LINQ statement

后端 未结 5 1125
一生所求
一生所求 2021-02-08 03:23

can someone please help me turn this nested structure into a single LINQ statement?

        EventLog[] logs = EventLog.GetEventLogs();
        for (int i = 0; i          


        
相关标签:
5条回答
  • 2021-02-08 03:54

    Have a look:

    List<Entries> result = new List<Entries>();
    
    GetEventLogs().Where(x => x.LogDisplayName.Equals("AAA")).ToList().ForEach(delegate(Log en)
    {
        en.Entries.Where(y => y.Source.Equals("BBB", StringComparison.InvariantCultureIgnoreCase)).ToList().ForEach(delegate(Entries ent)
        {
            result.Add(ent);
        });
    });
    
    0 讨论(0)
  • 2021-02-08 03:56

    Try this:

     EventLog[] logs = EventLog.GetEventLogs(); 
     remoteAccessLogs.AddRange(
       logs.Where(l => l.LogDisplayName.Equals("AAA"))
         .Select(l => l.Entries)
         .Where(le => le.Source.Equals("BBB"));
    

    However if performance is an issue I would expect this has at least the same algorithmic complexity, if not worse, as we are iterating over the list again to AddRange.

    0 讨论(0)
  • 2021-02-08 03:57

    Try the following:

    from log in logs 
    where log.LogDisplayName.Equals("AAA")
    select 
       (from entry in log.Entries
        where entry.Source.Equals("BBB")
        select entry);
    
    0 讨论(0)
  • 2021-02-08 04:01

    I have this solution, and I'm assuming that remoteAccessLogs is of type List

    remoteAccessLogs.AddRange(
    
            from log in EventLog.GetEventLogs()
            from entry in log.Entries.Cast<EventLogEntry>()
            select entry
        );
    

    Edit

    I forgot about the where clauses

    List<EventLogEntry> remoteAccessLogs = new List<EventLogEntry>();
    
    
        remoteAccessLogs.AddRange(
    
            from log in EventLog.GetEventLogs()
            where log.LogDisplayName.Equals("AAA")
            from entry in log.Entries.Cast<EventLogEntry>()
            where entry.Source.Equals("BBB")
            select entry
        );
    
    0 讨论(0)
  • 2021-02-08 04:14

    Nested loops usually end up with multiple "from" clauses (which are converted into calls to SelectMany by the compiler):

    var remoteAccessLogs = from log in EventLogs.GetEventLogs()
                           where log.LogDisplayName == "AAA"
                           from entry in log.Entries
                           where entry.Source == "BBB"
                           select entry;
    

    (That's assuming that remoteAccessLogs is empty before this call, and that you're happy iterating over it directly - you can call ToList() if you want a List<T>.)

    Here's the dot notation form:

    var remoteAccessLogs = EventLogs.GetEventLogs()
                                    .Where(log => log.LogDisplayName == "AAA")
                                    .SelectMany(log => log.Entries)
                                    .Where(entry => entry.Source == "BBB");
    

    Or for a list:

    var remoteAccessLogs = EventLogs.GetEventLogs()
                                    .Where(log => log.LogDisplayName == "AAA")
                                    .SelectMany(log => log.Entries)
                                    .Where(entry => entry.Source == "BBB")
                                    .ToList();
    

    Note that I've used the overloaded == for string as I find it easier to read than calling the Equals method. Either will work though.

    0 讨论(0)
提交回复
热议问题