How to select each broken line and group using other members in linq?

How to select many shared lines and group them using other elements in linq?

class LogData { public string IndexPattern {get; set;} public string Version {get;set;} public string Type1 {get; set;} public string Type2 {get; set;} //here has a constructor of this class } 

I have a list of log data that have a lot of log data. An index template is a set of journal index that uses the delimiter ",".

 List<LogData> logList = new List<LogData>(); logList.add(new LogData("1,2,4", "Ver1", "pro" , "etc" ) ); logList.add(new LogData("1", "Ver2", "pro" , "etc" ) ); logList.add(new LogData("2", "Ver1", "pro" , "etc" ) ); logList.add(new LogData("1,2,4", "Ver1", "pro" , "etc" ) ); logList.add(new LogData("1,5", "Ver2", "pro" , "set" ) ); 

And I want to separate the index templates and the group by all members like this.

 [Index] [Version] [Type1] [Type2] [Count] 1 Ver1 pro etc 2 2 Ver1 pro etc 2 4 Ver2 pro etc 2 1 Ver2 pro etc 1 1 Ver2 pro set 1 5 Ver2 pro set 1 4 Ver2 pro set 1 

And I will write linq like this to group at first.

 var LogGroup = HackingLogs.GroupBy(g => new { IndexPattern = g.IndexPattern.SelectMany( new { Index = c => c }), //I must select many to get each splited string g.Version, g.Type1, g.Type2 }); //I group by this for each splited string and all member pairs to select 

But he cannot group. so i cant use select. Can I answer this problem?

+5
source share
2 answers

You can first flatten IndexPattern with SelectMany and project all other elements. Finally, group over all columns and get a graph. This should give the expected result: -

  var res = logList.SelectMany(x => x.IndexPattern.Split(',') .Select(z => new { Index = z, Version = x.Version, Type1 = x.Type1, Type2 = x.Type2 })) .GroupBy(x => new { x.Index, x.Version, x.Type1, x.Type2 }) .Select(x => new { Index = x.Key.Index, Version = x.Key.Version, Type1 = x.Key.Type1, Type2 = x.Key.Type2, Count = x.Count() }); 

Working script.

+3
source

Today I learned Linq magic . Here is the code without using Linq

I found this problem interesting, so just submit my attempt.

 using System; using System.Collections.Generic; public class Program { public class LogData { public string IndexPattern {get; set;} public string Version {get;set;} public string Type1 {get; set;} public string Type2 {get; set;} //here has a constructor of LogData class public LogData(string indexPattern, string version, string type1, string type2){ IndexPattern = indexPattern; Version = version; Type1 = type1; Type2 = type2; } } public class GridData { public string Index {get; set;} public string Version {get;set;} public string Type1 {get; set;} public string Type2 {get; set;} public int count {get;set;} //here has a constructor of GridData class public GridData(string indexPattern, string version, string type1, string type2, int count){ Index = indexPattern; Version = version; Type1 = type1; Type2 = type2; this.count = count; } } public static void Main(){ //Inputs List<LogData> logList = new List<LogData>(); logList.Add(new LogData("1,2,4", "Ver1", "pro" , "etc" ) ); logList.Add(new LogData("1", "Ver2", "pro" , "etc" ) ); logList.Add(new LogData("2", "Ver1", "pro" , "etc" ) ); logList.Add(new LogData("1,2,4", "Ver1", "pro" , "etc" ) ); logList.Add(new LogData("1,5", "Ver2", "pro" , "set" ) ); //Calculate the results Dictionary<string, GridData> result = GetResult(logList); Display(result); } //Read all data and Get result in tabular format public static Dictionary<string, GridData> GetResult(List<LogData> logList){ //Initialization of local variable List<LogData> elements = new List<LogData>(); Dictionary<string, GridData> output = new Dictionary<string, GridData>(); //Iterate through each input foreach(LogData ld in logList){ LogData temp = new LogData("", "", "", ""); //Check for multiple Indexs in one list if(ld.IndexPattern.Contains(",")){ string[] strArr = ld.IndexPattern.Split(','); //Consider each index as one record; Time complexity: O(n*m) very bad foreach(string s1 in strArr){ temp = new LogData(s1, ld.Version, ld.Type1, ld.Type2); elements.Add(temp); } } //Else record as it is else{ elements.Add(ld); } } //List elements contains all seperated records foreach(LogData logData in elements){ //Create unique key by concatenating all properties into string string key = logData.IndexPattern + "_" + logData.Version +"_"+ logData.Type1 +"_"+logData.Type2; //Increment counter if record is already exist if(output.ContainsKey(key)) output[key].count++; else{ //Insert new record GridData gd = new GridData(logData.IndexPattern, logData.Version, logData.Type1, logData.Type2, 1); output.Add(key, gd); } } return output; } //Display in tabular format public static void Display(Dictionary<string, GridData> output){ foreach(string str in output.Keys){ Console.WriteLine(output[str].Index +"\t"+ output[str].Version +"\t"+ output[str].Type1 +"\t"+ output[str].Type2 +"\t"+ output[str].count); } } } 

Improvements are welcome. Dotnetfiddler

+1
source

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


All Articles