C# 多列数据转换
我从一个数据源接收数据,在将信息发送到UI进行显示之前,我需要对该数据源进行透视<代码>我对旋转的概念不太熟悉&我不知道该怎么做。 该问题分为两部分:C# 多列数据转换,c#,.net,linq,c#-4.0,pivot,C#,.net,Linq,C# 4.0,Pivot,我从一个数据源接收数据,在将信息发送到UI进行显示之前,我需要对该数据源进行透视我对旋转的概念不太熟悉&我不知道该怎么做。 该问题分为两部分: 形成头部 旋转数据以匹配标题 要记住的事情: class Program { static void Main(string[] args) { var _staticColumnCount = 2; //Columns that should not be pivoted
class Program
{
static void Main(string[] args)
{
var _staticColumnCount = 2; //Columns that should not be pivoted
var _dynamicColumnCount = 2; // Columns which needs to be pivoted to form header
var _valueColumnCount = 1; //Columns that represent Actual value
var valueColumnIndex = 4; //Assuming index starts with 0;
List<List<string>> headerInfo = new List<List<string>>();
headerInfo.Add(new List<string> {"Product Three", "Item Ten"});
headerInfo.Add(new List<string> {"Product Two", "Item Five"});
headerInfo.Add(new List<string> {"Product Two", "Item Seven"});
headerInfo.Add(new List<string> {"Product Two", "Item Nine"});
headerInfo.Add(new List<string> {"Product One", "Item One"});
headerInfo.Add(new List<string> {"Product One", "Item Two"});
headerInfo.Add(new List<string> {"Product One", "Item Four"});
headerInfo.Add(new List<string> {"Product One", "Item Six"});
headerInfo.Add(new List<string> {"Product One", "Item Eight"});
headerInfo.Add(new List<string> {"Product One", "Item Eleven"});
List<List<string>> data = new List<List<string>>();
data.Add(new List<string> {"Global", "Europe", "Product One", "Item One", "579984.59"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Two", "314586.73"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item One", "62735.13"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Five", "12619234.69"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Five", "8953713.39"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Two", "124267.4"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Four", "482338.49"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Four", "809185.13"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Four", "233101"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Two", "120561.65"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Six", "1517359.37"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Six", "382590.45"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Eight", "661835.64"});
data.Add(new List<string> {"Global", "Europe", "Product Three", "Item Three", "0"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Eight", "0"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Five", "3478145.38"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Six", "0"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Seven", "4247059.97"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Seven", "2163718.01"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Seven", "2158782.48"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Nine", "72634.46"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Nine", "127500"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item One", "110964.44"});
data.Add(new List<string> {"Global", "Asia", "Product Three", "Item Ten", "2064.99"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Eleven", "0"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Nine", "1250"});
}
}
静态列。
动态列
值列
动态、静态和值列的数量没有限制
class Program
{
static void Main(string[] args)
{
var _staticColumnCount = 2; //Columns that should not be pivoted
var _dynamicColumnCount = 2; // Columns which needs to be pivoted to form header
var _valueColumnCount = 1; //Columns that represent Actual value
var valueColumnIndex = 4; //Assuming index starts with 0;
List<List<string>> headerInfo = new List<List<string>>();
headerInfo.Add(new List<string> {"Product Three", "Item Ten"});
headerInfo.Add(new List<string> {"Product Two", "Item Five"});
headerInfo.Add(new List<string> {"Product Two", "Item Seven"});
headerInfo.Add(new List<string> {"Product Two", "Item Nine"});
headerInfo.Add(new List<string> {"Product One", "Item One"});
headerInfo.Add(new List<string> {"Product One", "Item Two"});
headerInfo.Add(new List<string> {"Product One", "Item Four"});
headerInfo.Add(new List<string> {"Product One", "Item Six"});
headerInfo.Add(new List<string> {"Product One", "Item Eight"});
headerInfo.Add(new List<string> {"Product One", "Item Eleven"});
List<List<string>> data = new List<List<string>>();
data.Add(new List<string> {"Global", "Europe", "Product One", "Item One", "579984.59"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Two", "314586.73"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item One", "62735.13"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Five", "12619234.69"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Five", "8953713.39"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Two", "124267.4"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Four", "482338.49"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Four", "809185.13"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Four", "233101"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Two", "120561.65"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Six", "1517359.37"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Six", "382590.45"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item Eight", "661835.64"});
data.Add(new List<string> {"Global", "Europe", "Product Three", "Item Three", "0"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Eight", "0"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Five", "3478145.38"});
data.Add(new List<string> {"Global", "Asia", "Product One", "Item Six", "0"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Seven", "4247059.97"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Seven", "2163718.01"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Seven", "2158782.48"});
data.Add(new List<string> {"Global", "North America", "Product Two", "Item Nine", "72634.46"});
data.Add(new List<string> {"Global", "Europe", "Product Two", "Item Nine", "127500"});
data.Add(new List<string> {"Global", "North America", "Product One", "Item One", "110964.44"});
data.Add(new List<string> {"Global", "Asia", "Product Three", "Item Ten", "2064.99"});
data.Add(new List<string> {"Global", "Europe", "Product One", "Item Eleven", "0"});
data.Add(new List<string> {"Global", "Asia", "Product Two", "Item Nine", "1250"});
}
}
类程序
{
静态void Main(字符串[]参数)
{
var _staticColumnCount=2;//不应旋转的列
var _dynamicColumnCount=2;//需要旋转以形成标题的列
var _valueColumnCount=1;//表示实际值的列
var valueColumnIndex=4;//假设索引以0开头;
列表标题信息=新列表();
添加(新列表{“产品三”,“项目十”});
添加(新列表{“产品二”,“项目五”});
添加(新列表{“产品二”,“项目七”});
添加(新列表{“产品二”,“项目九”});
添加(新列表{“产品一”,“项目一”});
添加(新列表{“产品一”,“项目二”});
添加(新列表{“产品一”,“项目四”});
添加(新列表{“产品一”,“项目六”});
添加(新列表{“产品一”,“项目八”});
添加(新列表{“产品一”,“项目十一”});
列表数据=新列表();
新增(新名单{“全球”、“欧洲”、“产品一”、“项目一”、“579984.59”);
增加(新的清单{“全球”、“北美”、“产品一”、“项目二”、“314586.73”);
增加(新的清单{“全球”、“亚洲”、“产品一”、“项目一”、“62735.13”);
增加(新的清单{“全球”、“亚洲”、“产品二”、“项目五”、“12619234.69”);
增加(新的清单{“全球”、“北美”、“产品二”、“项目五”、“8953713.39”);
增加(新的清单{“全球”、“欧洲”、“产品一”、“项目二”、“124267.4”});
增加(新的清单{“全球”、“亚洲”、“产品一”、“项目四”、“482338.49”);
增加(新的清单{“全球”、“北美”、“产品一”、“项目四”、“809185.13”);
新增(新名单{“全球”、“欧洲”、“产品一”、“项目四”、“233101”});
增加(新的清单{“全球”、“亚洲”、“产品一”、“项目二”、“120561.65”});
新增(新名单{“全球”、“北美”、“产品一”、“项目六”、“1517359.37”);
增加(新的清单{“全球”、“欧洲”、“产品一”、“项目六”、“382590.45”);
新增(新名单{“全球”、“北美”、“产品一”、“项目八”、“661835.64”});
添加(新列表{“全球”、“欧洲”、“产品三”、“项目三”、“0”});
添加(新清单{“全球”、“欧洲”、“产品一”、“项目八”、“0”});
增加(新的清单{“全球”、“欧洲”、“产品二”、“项目五”、“3478145.38”);
添加(新列表{“全球”、“亚洲”、“产品一”、“项目六”、“0”});
增加(新的清单{“全球”、“北美”、“产品二”、“项目七”、“4247059.97”);
增加(新的清单{“全球”、“亚洲”、“产品二”、“项目七”、“2163718.01”);
增加(新的清单{“全球”、“欧洲”、“产品二”、“项目七”、“2158782.48”);
增加(新的清单{“全球”、“北美”、“产品二”、“项目九”、“72634.46”);
新增(新名单{“全球”、“欧洲”、“产品二”、“项目九”、“127500”);
添加(新的清单{“全球”、“北美”、“产品一”、“项目一”、“110964.44”});
增加(新的清单{“全球”、“亚洲”、“产品三”、“项目十”、“2064.99”});
添加(新清单{“全球”、“欧洲”、“产品一”、“项目十一”、“0”});
增加(新的清单{“全球”、“亚洲”、“产品二”、“项目九”、“1250”);
}
}
您可以使用库以以下方式按任意列数创建透视表(不要忘记安装“NReco.PivotData”nuget软件包):
//数据集中的行表示为“数组”
//让我们定义“字段名”->“字段索引”映射
var fieldToIndex=新字典(){
{“区域L1”,0},
{“区域L2”,1},
{“产品L1”,2},
{“产品L2”,3},
{“Val”,4}
};
//创建多维数据集
var pvtData=新的数据透视(
//按4个维度分组
新[]{“区域L1”、“区域L2”、“产品L1”、“产品L2”},
//值(对多个值使用CompositeAggerFactory)
新苏门答腊工厂(“Val”);
ProcessData(数据,(行,字段)=>((IList)行)[fieldToIndex[field]]);
//通过分组数据创建透视表数据模型
var pvtTbl=新数据透视表(
//行的尺寸
新[]{“区域L1”,“区域L2”},
//柱的尺寸
新[]{“产品L1”,“产品L2”},
pvtData);
//现在您可以遍历“pvtTbl.RowKeys”和“pvtTbl.ColumnKeys”
//要获取行\列标题标签并使用“pvtTbl.GetValue()”
//或“pvtTbl[]”以透视表获取值
//您可以轻松地将透视表渲染为HTM
var working =
data
.Select(d => new
{
Region_L1 = d[0],
Region_L2 = d[1],
Product_L1 = d[2],
Product_L2 = d[3],
Value = double.Parse(d[4]),
});
var output =
working
.GroupBy(x => new { x.Region_L1, x.Region_L2 }, x => new { x.Product_L1, x.Product_L2, x.Value })
.Select(x => new { x.Key, Lookup = x.ToLookup(y => new { y.Product_L1, y.Product_L2 }, y => y.Value) })
.Select(x => new
{
x.Key.Region_L1,
x.Key.Region_L2,
P_One_One = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item One" }].Sum(),
P_One_Two = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item Two" }].Sum(),
P_One_Four = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item Four" }].Sum(),
P_One_Six = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item Six" }].Sum(),
P_One_Eight = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item Eight" }].Sum(),
P_One_Eleven = x.Lookup[new { Product_L1 = "Product One", Product_L2 = "Item Eleven" }].Sum(),
P_Two_Five = x.Lookup[new { Product_L1 = "Product Two", Product_L2 = "Item Five" }].Sum(),
P_Two_Seven = x.Lookup[new { Product_L1 = "Product Two", Product_L2 = "Item Seven" }].Sum(),
P_Two_Nine = x.Lookup[new { Product_L1 = "Product Two", Product_L2 = "Item Nine" }].Sum(),
P_Three_Three = x.Lookup[new { Product_L1 = "Product Three", Product_L2 = "Item Three" }].Sum(),
P_Three_Ten = x.Lookup[new { Product_L1 = "Product Three", Product_L2 = "Item Ten" }].Sum(),
});
var output =
working
.GroupBy(x => new { x.Region_L1, x.Region_L2 }, x => new { x.Product_L1, x.Product_L2, x.Value })
.Select(x => new { x.Key, Lookup = x.ToLookup(y => new { y.Product_L1, y.Product_L2 }, y => y.Value) })
.Select(x => new
{
x.Key.Region_L1,
x.Key.Region_L2,
Headers =
headerInfo
.Select(y => new { Product_L1 = y[0], Product_L2 = y[1] })
.Select(y => new { y.Product_L1, y.Product_L2, Value = x.Lookup[y].Sum() })
.ToArray(),
});
public class PivotData
{
public IReadOnlyList<PivotValues> Columns { get; set; }
public IReadOnlyList<PivotDataRow> Rows { get; set; }
}
public class PivotDataRow
{
public PivotValues Data { get; set; }
public IReadOnlyList<PivotValues> Values { get; set; }
}
public class PivotValues : IReadOnlyList<string>, IEquatable<PivotValues>, IComparable<PivotValues>
{
readonly IReadOnlyList<string> source;
readonly int offset, count;
public PivotValues(IReadOnlyList<string> source) : this(source, 0, source.Count) { }
public PivotValues(IReadOnlyList<string> source, int offset, int count)
{
this.source = source;
this.offset = offset;
this.count = count;
}
public string this[int index] => source[offset + index];
public int Count => count;
public IEnumerator<string> GetEnumerator()
{
for (int i = 0; i < count; i++)
yield return this[i];
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public override int GetHashCode()
{
unchecked
{
var comparer = EqualityComparer<string>.Default;
int hash = 17;
for (int i = 0; i < count; i++)
hash = hash * 31 + comparer.GetHashCode(this[i]);
return hash;
}
}
public override bool Equals(object obj) => Equals(obj as PivotValues);
public bool Equals(PivotValues other)
{
if (this == other) return true;
if (other == null) return false;
var comparer = EqualityComparer<string>.Default;
for (int i = 0; i < count; i++)
if (!comparer.Equals(this[i], other[i])) return false;
return true;
}
public int CompareTo(PivotValues other)
{
if (this == other) return 0;
if (other == null) return 1;
var comparer = Comparer<string>.Default;
for (int i = 0; i < count; i++)
{
var compare = comparer.Compare(this[i], other[i]);
if (compare != 0) return compare;
}
return 0;
}
public override string ToString() => string.Join(", ", this); // For debugging
}
public static PivotData ToPivot(this List<List<string>> data, int rowDataCount, int columnDataCount, int valueDataCount)
{
int rowDataStart = 0;
int columnDataStart = rowDataStart + rowDataCount;
int valueDataStart = columnDataStart + columnDataCount;
var columns = data
.Select(r => new PivotValues(r, columnDataStart, columnDataCount))
.Distinct()
.OrderBy(c => c) // Optional
.ToList();
var emptyValues = new PivotValues(new string[valueDataCount]); // For missing (row, column) intersection
var rows = data
.GroupBy(r => new PivotValues(r, rowDataStart, rowDataCount))
.Select(rg => new PivotDataRow
{
Data = rg.Key,
Values = columns.GroupJoin(rg,
c => c,
r => new PivotValues(r, columnDataStart, columnDataCount),
(c, vg) => vg.Any() ? new PivotValues(vg.First(), valueDataStart, valueDataCount) : emptyValues
).ToList()
})
.OrderBy(r => r.Data) // Optional
.ToList();
return new PivotData { Columns = columns, Rows = rows };
}
var pivotData = data.ToPivot(2, 2, 1);
var json = JsonConvert.SerializeObject(pivotData);
var pivotData2 = JsonConvert.DeserializeObject<PivotData>(json);
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
namespace pivot
{
class Program
{
static void Main(string[] args)
{
var _staticColumnCount = 2; //Columns that should not be pivoted
var _dynamicColumnCount = 2; // Columns which needs to be pivoted to form header
var _valueColumnCount = 1; //Columns that represent Actual value
var valueColumnIndex = 4; //Assuming index starts with 0;
List<List<string>> headerInfo = new List<List<string>>();
headerInfo.Add(new List<string> { "Product Three", "Item Three" });
headerInfo.Add(new List<string> { "Product Two", "Item Five" });
headerInfo.Add(new List<string> { "Product Two", "Item Seven" });
headerInfo.Add(new List<string> { "Product Two", "Item Nine" });
headerInfo.Add(new List<string> { "Product One", "Item One" });
headerInfo.Add(new List<string> { "Product One", "Item Two" });
headerInfo.Add(new List<string> { "Product One", "Item Four" });
headerInfo.Add(new List<string> { "Product One", "Item Six" });
headerInfo.Add(new List<string> { "Product One", "Item Eight" });
headerInfo.Add(new List<string> { "Product One", "Item Eleven" });
headerInfo.Add(new List<string> { "Product Three", "Item Ten" });
List<List<string>> data = new List<List<string>>();
data.Add(new List<string> { "Global", "Europe", "Product One", "Item One", "579984.59" });
data.Add(new List<string> { "Global", "North America", "Product One", "Item Two", "314586.73" });
data.Add(new List<string> { "Global", "Asia", "Product One", "Item One", "62735.13" });
data.Add(new List<string> { "Global", "Asia", "Product Two", "Item Five", "12619234.69" });
data.Add(new List<string> { "Global", "North America", "Product Two", "Item Five", "8953713.39" });
data.Add(new List<string> { "Global", "Europe", "Product One", "Item Two", "124267.4" });
data.Add(new List<string> { "Global", "Asia", "Product One", "Item Four", "482338.49" });
data.Add(new List<string> { "Global", "North America", "Product One", "Item Four", "809185.13" });
data.Add(new List<string> { "Global", "Europe", "Product One", "Item Four", "233101" });
data.Add(new List<string> { "Global", "Asia", "Product One", "Item Two", "120561.65" });
data.Add(new List<string> { "Global", "North America", "Product One", "Item Six", "1517359.37" });
data.Add(new List<string> { "Global", "Europe", "Product One", "Item Six", "382590.45" });
data.Add(new List<string> { "Global", "North America", "Product One", "Item Eight", "661835.64" });
data.Add(new List<string> { "Global", "Europe", "Product Three", "Item Three", "0" });
data.Add(new List<string> { "Global", "Europe", "Product One", "Item Eight", "0" });
data.Add(new List<string> { "Global", "Europe", "Product Two", "Item Five", "3478145.38" });
data.Add(new List<string> { "Global", "Asia", "Product One", "Item Six", "0" });
data.Add(new List<string> { "Global", "North America", "Product Two", "Item Seven", "4247059.97" });
data.Add(new List<string> { "Global", "Asia", "Product Two", "Item Seven", "2163718.01" });
data.Add(new List<string> { "Global", "Europe", "Product Two", "Item Seven", "2158782.48" });
data.Add(new List<string> { "Global", "North America", "Product Two", "Item Nine", "72634.46" });
data.Add(new List<string> { "Global", "Europe", "Product Two", "Item Nine", "127500" });
data.Add(new List<string> { "Global", "North America", "Product One", "Item One", "110964.44" });
data.Add(new List<string> { "Global", "Asia", "Product Three", "Item Ten", "2064.99" });
data.Add(new List<string> { "Global", "Europe", "Product One", "Item Eleven", "0" });
data.Add(new List<string> { "Global", "Asia", "Product Two", "Item Nine", "1250" });
Stopwatch stopwatch = new Stopwatch();
stopwatch.Start();
Reducer reducer = new Reducer();
reducer.headerCount = headerInfo.Count;
reducer.headerCount = headerInfo.Count;
var resultCount = (int)Math.Ceiling((double)data.Count / (double)reducer.headerCount);
ValueArray[,] results = new ValueArray[resultCount, _staticColumnCount + reducer.headerCount];
reducer.headerDict = new Dictionary<IEnumerable<string>, int>(new MyComparer());
reducer.skipCols = _staticColumnCount;
reducer.headerKeys = _dynamicColumnCount;
reducer.rowDict = new Dictionary<IEnumerable<string>, int>(new MyComparer());
reducer.currentLine = 0;
reducer.valueCount = _valueColumnCount;
for (int i = 0; i < reducer.headerCount; i++)
{
reducer.headerDict.Add(headerInfo[i], i);
}
results = data.Aggregate(results, reducer.reduce);
stopwatch.Stop();
Console.WriteLine("millisecs: " + stopwatch.ElapsedMilliseconds);
for (int i = 0; i < resultCount; i++)
{
var curr_header = new string[reducer.headerCount];
IEnumerable<string> curr_key = null;
for (int j = 0; j < reducer.headerCount; j++)
{
curr_header[j] = "[" +
String.Join(",", (results[i, reducer.skipCols + j]?.values) ?? new string[0])
+ "]";
curr_key = curr_key ?? (results[i, reducer.skipCols + j]?.row_keys);
}
Console.WriteLine(String.Join(",", curr_key)
+ ": " + String.Join(",", curr_header)
);
}
Console.ReadKey();
// if you want to compare it to the accepted answer
stopwatch.Reset();
stopwatch.Start();
var pivotData = data.ToPivot(2, 2, 1); // with all needed classes/methods
stopwatch.Stop();
Console.WriteLine("millisecs: " + stopwatch.ElapsedMilliseconds);
Console.ReadKey();
}
internal class ValueArray
{
internal IEnumerable<string> row_keys;
internal string[] values;
}
internal class Reducer
{
internal int headerCount;
internal int skipCols;
internal int headerKeys;
internal int valueCount;
internal Dictionary<IEnumerable<string>, int> headerDict;
internal Dictionary<IEnumerable<string>, int> rowDict;
internal int currentLine;
internal ValueArray[,] reduce(ValueArray[,] results, List<string> line)
{
var header_col = headerDict[line.Skip(skipCols).Take(headerKeys)];
var row_keys = line.Take(skipCols);
var curr_values = new string[valueCount];
for (int i = 0; i < valueCount; i++)
{
curr_values[i] = line[skipCols + headerKeys + i];
}
if (rowDict.ContainsKey(row_keys))
{
results[rowDict[row_keys], skipCols + header_col] = new ValueArray();
results[rowDict[row_keys], skipCols + header_col].row_keys = row_keys;
results[rowDict[row_keys], skipCols + header_col].values = curr_values;
}
else
{
rowDict.Add(row_keys, currentLine);
results[currentLine, skipCols + header_col] = new ValueArray();
results[currentLine, skipCols + header_col].row_keys = row_keys;
results[currentLine, skipCols + header_col].values = curr_values;
currentLine++;
}
return results;
}
}
public class MyComparer : IEqualityComparer<IEnumerable<string>>
{
public bool Equals(IEnumerable<string> x, IEnumerable<string> y)
{
return x.SequenceEqual(y);
}
public int GetHashCode(IEnumerable<string> obj)
{
return obj.First().GetHashCode();
}
}
}
}