LINQ query on a list of Bool + String pairs. How to join lines without foreach?

has some doubts with LINQ queries on objects ...

I have descriptions of filters that I want to keep confidential, and at the given breakpoints in the code I set some flags active. At the end of processing, I want to filter out the active flags.

If any flags are active, I want to write them to the console. (I want all the marked control points to be on the same line, so I can possibly change the code to later throw an exception).

This is the code:

using System; using System.Collections.Generic; using System.Linq; using System.Xml; namespace checkpoints { public class Program { public static void Main(string[] args) { var filters = new Filters().FilterList; filters[0].flag = true; filters[2].flag = true; var query = filters.Where(f => f.flag).Select(f => f.desc); Console.WriteLine("Filter points active: "); string fpoints = System.String.Empty; foreach(string fp in query) { fpoints = fpoints + fp + System.Environment.NewLine; } Console.WriteLine(fpoints); } } public class Filters { public List<Filter> FilterList = new List<Filter>{}; public Filters() { foreach(var def in Filters.def_desc) { this.FilterList.Add(new Filter(false, def)); } } private readonly static string[] def_desc = new string[3] { "Filter AX2123: Failed file write.", "Filter XVB231: Failed table load.", "Filter FZD358: Transaction halted." }; public class Filter { public bool flag; public readonly string desc; public Filter(bool flag, string desc) { this.flag = flag; this.desc = desc; } } } } 

It works. My problem is the need to run LINQ for each of the results of the query (which I assume is an IEnumerable<Filter> ) to extract the rows. If I have already fulfilled the request (i.e. all the code has passed), why do I need to "run again"? It looks like it weighs terribly and not very elegant ... Any thoughts?

+4
source share
6 answers
 string fpoint=query.Aggregate((c, c1) => c + System.Environment.NewLine+ c1 ); 
+2
source

Call var query = filters.Where(f => f.flag).Select(f => f.desc); does not start the request. IEnumerable<Filter> returned by the call chain does not collect Filter objects until you list the results of the return in the foreach .

This is an advantage and disadvantage. The advantage is that you save all the processor time needed to evaluate your query in cases where the query results are not needed. The disadvantage is that if you need to list the results multiple times, the second time the system will recount the results again. The fix to fix this last problem is to immediately list the query results and put them in an array or list, for example:

 var queryResults = filters.Where(f => f.flag).Select(f => f.desc).ToList(); 
+2
source

Since dasblinkenlight and Daev already mentioned the deferred part of execution, I thought you would be interested to know that you can join strings without foreach by replacing

 foreach(string fp in query) { fpoints = fpoints + fp + System.Environment.NewLine; } 

with

 string.Join(Environment.NewLine, query) 
+2
source

Your query variable is an expression and will not be evaluated until it is listed (in foreach in your case). If you examine the query using the debugger, you will not see its contents as a Filter collection, rather a query, to get your results. This is called “deferred execution" and is pretty well described in this blog post (although this Linq-SQL applies to the same principles).

+1
source

If you want to get rid of your foreach, here is something you can try.

 string.Join(Environment.NewLine, query.ToArray()); 

Sorry if I didn’t read your question carefully enough :)

+1
source

What you need is a LINQ function called an aggregate. It combines list items together into one output.

A quick google shows this stackoverflow post showing how to use an aggregate function: Linq Aggregate Function

A simple example is to use the function here: http://blueonionsoftware.com/blog.aspx?p=509fa3f8-c125-4e61-9227-8ca4c4e29210 . This example uses commas, where you can use newlines instead.

0
source

Source: https://habr.com/ru/post/1387122/


All Articles