假设我有两个查询结果存储在两个不同的.csv文件(1.csv,2.csv)中,数据如下所示:1.csv:2.csvdim1& dim2将出现在每个查询表结果中,字段……
List连接可以按如下方式完成
private void JoinList(List<List<string>> listToJoin, int keysNumber, int paddingAfterKeys = 0) { // you need the padding if an element is found only in the second list // this is a list that will be added to the result var paddingList = new List<string>(); for (var i = 0; i < paddingAfterKeys; i++) { // feel free to change it to null or what value fit your solution paddingList.Add("0"); } foreach (var t in listToJoin) { // create a key var keyString = string.Join(',', t.Take(keysNumber)); if (result.TryGetValue(keyString, out var fieldsList)) { // if the key already exist just add the values except the keys values this way you won't get duplicate keys fieldsList.AddRange(t.Skip(keysNumber)); } else { // get the keys, pad the list if needed and the rest of the keys fieldsList = t.Take(keysNumber).ToList(); fieldsList.AddRange(paddingList); fieldsList.AddRange(t.Skip(keysNumber)); // add new key to the dictionary and set the value in my program the result was a private variable of the class for the ease of use. result[keyString] = fieldsList; } } }
如果密钥不是第一个,您可以执行一个列表来保存索引并从索引中获取密钥。
为了协调这个,你需要这样的东西:
public void ProcessLists() { const int keysNumber = 2; var totalLength = R1[0].Count + R2[0].Count - keysNumber; // add first list to dictionary JoinList(R1, keysNumber); var paddingAfterKeys = R1[0].Count - keysNumber; // add the second list to dictionary and add padding if a key was not found in dictionary JoinList(R2, keysNumber, paddingAfterKeys); // add padding to the end if a key was found in first list but not in second paddingAfterKeys = R2[0].Count - keysNumber; var paddingList = new List<string>(); for (var i = 0; i < paddingAfterKeys; i++) { paddingList.Add("0"); } foreach (var keyValuePair in result.Where(x => x.Value.Count < totalLength)) { keyValuePair.Value.AddRange(paddingList); } }
您可以创建在CSV记录之后建模的强类型对象,包括输入记录和最终输出记录。然后使用LINQ组合您的记录。
这是一个小例子。
using System; using System.Collections.Generic; using System.Linq; namespace ConsoleApp2 { class Program { public static List<CsvOne> InitCsvOne() { //mock pulling in data List<CsvOne> csv = new List<CsvOne> { new CsvOne { dim1 = 2,dim2 = "wwa", field1 =3 }, new CsvOne { dim1 = 1, dim2 = "arr", field1 = 6} }; return csv; } public static List<CsvTwo> InitCsvTwo() { //mock pulling in data List<CsvTwo> csv = new List<CsvTwo> { new CsvTwo { dim1 = 2,dim2 = "jaja", field2 = 1000, field3 =2 }, new CsvTwo { dim1 = 3, dim2 = "waa", field2 = 1000, field3 = 3 }, new CsvTwo { dim1 = 1, dim2 = "arr", field2 = 2000, field3 = 4}, }; return csv; } static void Main(string[] args) { var csvOne = InitCsvOne(); var csvTwo = InitCsvTwo(); var csvThree = new List<CsvThree>(); //get the ball rolling with csv one csvOne.ForEach(record =>csvThree.Add(new CsvThree(record))); //now either match up one with two or add with field1 being 0 //if we already have a matching dim1 and dim2, lets update the two new fields. //note that we do not add another one if there are two the same csvTwo.ForEach(record => { if (csvThree.Any(t => (t.dim1 == record.dim1 && t.dim2 == record.dim2))) { //combine the match with fields 2 and 3 var theMatch = csvThree.FirstOrDefault(t => (t.dim1 == record.dim1 && t.dim2 == record.dim2)); theMatch.field2 = record.field2; theMatch.field3 = record.field3; } else //add this new record to the list { csvThree.Add(new CsvThree(record)); } }); csvThree = csvThree.OrderBy(t => t.dim1).ThenBy(t=>t.dim2).ToList(); //or whatever you want //check it Console.WriteLine($"Csv One Records"); Console.WriteLine($" dim1|dim2|field1"); csvOne.ForEach(record => { Console.WriteLine(record.ToString()); }); Console.WriteLine($"Csv Two Records"); Console.WriteLine($"dim1|dim2|field2|field3"); csvTwo.ForEach(record => { Console.WriteLine(record.ToString()); }); Console.WriteLine($"Csv Three Records"); Console.WriteLine($"dim1|dim2|field1|field2|field3"); csvThree.ForEach(record => { Console.WriteLine(record.ToString()); }); Console.WriteLine("Press any key to exit..."); var wait = Console.ReadKey(); } } public abstract class dim { public int dim1 { get; set; } public string dim2 { get; set; } } public class CsvOne:dim { public int field1 { get; set; } public CsvOne() { field1 = 0; } public override string ToString() { return $"{dim1} |{dim2}|{field1}"; } } public class CsvTwo:dim { public int field2 { get; set; } public int field3 { get; set; } public CsvTwo() { field2 = field3 = 0; } public override string ToString() { return $"{dim1} |{dim2}|{field2}|{field3}"; } } public class CsvThree : dim { public int field1 { get; set; } public int field2 { get; set; } public int field3 { get; set; } public CsvThree() { field1 = field2 = field3 = 0; } public CsvThree(CsvOne value) { field1 = field2 = field3 = 0; dim1 = value.dim1; dim2 = value.dim2; field1 = value.field1; } public CsvThree(CsvTwo value) { field1 = field2 = field3 = 0; dim1 = value.dim1; dim2 = value.dim2; field2 = value.field2; field3 = value.field3; } public override string ToString() { return $"{dim1} |{dim2}|{field1}|{field2}|{field3}"; } } }
结果是:
Csv One Records dim1|dim2|field1 2 |wwa|3 1 |arr|6 Csv Two Records dim1|dim2|field2|field3 2 |jaja|1000|2 3 |waa|1000|3 1 |arr|2000|4 Csv Three Records dim1|dim2|field1|field2|field3 1 |arr|6|2000|4 2 |jaja|0|1000|2 2 |wwa|3|0|0 3 |waa|0|1000|3 Press any key to exit...