如何与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
}
我有一个日志数据列表,这些数据具有许多日志基准。索引模式是使用定界符","的日志索引集。
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" ) );
我想要这样的分组索引模式和组。
[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
,我先写下这样的linq。
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
,但不能分组。因此我无法使用SELECT。我可以解决这个问题吗?
您可以首先使用SelectMany和Project所有其他元素来板 IndexPattern
。最后,按所有列分组并获得计数。这应该给您预期的输出: -
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()
});
工作小提琴。
今天,我学到了linq 的魔法。这是不使用Linq
的代码我发现这个问题很有趣,所以只会发布我的尝试。
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);
}
}
}
改进得到赞赏。dotnetfiddler